GUI improvments and fixes - Alex
[terminatorX.git] / terminatorX / src / tX_vtt.cc
1 /*
2     terminatorX - realtime audio scratching software
3     Copyright (C) 1999-2002  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_vtt.cc
20  
21     Description: This implements the new virtual turntable class. It replaces
22                  the old turntable.c from terminatorX 3.2 and earlier. The lowpass
23                  filter is based on some sample code by Paul Kellett
24                  <paul.kellett@maxim.abel.co.uk>
25                  
26     08 Dec 1999 - Switched to the new audiofile class            
27 */    
28    
29 #include "tX_vtt.h"
30 #include "tX_global.h"
31 #include <stdio.h>
32 #include "malloc.h"
33 #include <math.h>
34 #include "tX_mastergui.h"
35 #include "tX_sequencer.h"
36 #include <glib.h>
37
38 #ifdef HAVE_CONFIG_H
39 #include <config.h>
40 #endif
41
42 #ifdef USE_3DNOW
43 #include "3dnow.h"
44 #endif
45
46
47 #ifdef DEBUG
48 #define tX_freemem(ptr, varname, comment); fprintf(stderr, "** free() [%s] at %08x. %s.\n", varname, ptr, comment); free(ptr);
49 #define tX_malloc(ptr, varname, comment, size, type); fprintf(stderr, "**[1/2] malloc() [%s]. Size: %i. %s.\n", varname, size, comment); ptr=type malloc(size); fprintf(stderr, "**[2/2] malloc() [%s]. ptr: %08x.\n", varname, ptr);
50 #else
51 #define tX_freemem(ptr, varname, comment); free(ptr);
52 #define tX_malloc(ptr, varname, comment, size, type); ptr=type malloc(size);
53 #endif
54
55 #include "tX_loaddlg.h"
56
57 #define USE_PREFETCH 1
58
59 #ifdef USE_PREFETCH
60 #define my_prefetch(base, index); __asm__  __volatile__ ("prefetch index(%0)\n" : : "r" (base));
61 #define my_prefetchw(base, index); __asm__  __volatile__ ("prefetchw index(%0)\n" : : "r" (base));
62 #else
63 #define my_prefetch(base, index);  /* NOP */;
64 #define my_prefetchw(base, index); /* NOP */;
65 #endif
66
67 extern void build_vtt_gui(vtt_class *);
68 extern void gui_set_name(vtt_class *vtt, char *newname);
69 extern void gui_set_filename(vtt_class *vtt, char *newname);
70 extern void delete_gui(vtt_class *vtt);
71 extern void gui_update_display(vtt_class *vtt);
72 extern void gui_clear_master_button(vtt_class *vtt);
73 extern void cleanup_vtt(vtt_class *vtt);
74 extern int vg_get_current_page(vtt_class *vtt);
75
76 int vtt_class::vtt_amount=0;
77 list <vtt_class *> vtt_class::main_list;
78 list <vtt_class *> vtt_class::render_list;
79 int16_t* vtt_class::mix_out_buffer=NULL;
80 f_prec * vtt_class::mix_buffer=NULL;
81 f_prec * vtt_class::mix_buffer_end=NULL;
82 int vtt_class::solo_ctr=0;
83
84 int vtt_class::samples_in_mix_buffer=0;
85 pthread_mutex_t vtt_class::render_lock=PTHREAD_MUTEX_INITIALIZER;
86 f_prec vtt_class::master_volume=1.0;
87 f_prec vtt_class::res_master_volume=1.0;
88 f_prec vtt_class::saturate_fac=0.1;
89 int vtt_class::do_saturate=0;
90 vtt_class * vtt_class::sync_master=NULL;
91 int vtt_class::master_triggered=0;
92 int vtt_class::master_triggered_at=0;
93 vtt_class * vtt_class::focused_vtt=NULL;
94 f_prec vtt_class::mix_max_l=0;
95 f_prec vtt_class::mix_max_r=0;
96 f_prec vtt_class::vol_channel_adjust=1.0;
97
98 #define GAIN_AUTO_ADJUST 0.8
99
100 vtt_class :: vtt_class (int do_create_gui)
101 {       
102         vtt_amount++;
103         sprintf (name, "Turntable %i", vtt_amount);
104         strcpy(filename, "NONE");
105         buffer=NULL;
106         samples_in_buffer=0;
107         
108         set_volume(1);
109         set_pitch(1);
110         
111         autotrigger=1;
112         loop=1;
113         
114         is_playing=0;
115         is_sync_master=0;
116         is_sync_client=0;
117         sync_cycles=0,
118         sync_countdown=0;
119         
120         x_control=CONTROL_SCRATCH;
121         y_control=CONTROL_CUTOFF;
122         
123         lp_enable=0;
124         lp_reso=0.8;
125         lp_freq=0.3;
126         lp_gain=1;
127         lp_setup(lp_gain, lp_reso, lp_freq);
128         lp_reset();
129         
130         ec_enable=0;
131         ec_length=0.5;
132         ec_feedback=0.3;
133         ec_clear_buffer();
134         ec_set_length(0.5);
135         ec_set_pan(0);
136         ec_set_volume(1);
137         
138         main_list.push_back(this);
139
140         /* "connecting" the seq-parameters */
141         
142         sp_speed.set_vtt((void *) this);
143         sp_volume.set_vtt((void *) this);       
144         sp_pitch.set_vtt((void *) this);        
145         sp_pan.set_vtt((void *) this);
146         sp_trigger.set_vtt((void *) this);      
147         sp_loop.set_vtt((void *) this); 
148         sp_sync_client.set_vtt((void *) this);  
149         sp_sync_cycles.set_vtt((void *) this);  
150         sp_lp_enable.set_vtt((void *) this);    
151         sp_lp_gain.set_vtt((void *) this);      
152         sp_lp_reso.set_vtt((void *) this);      
153         sp_lp_freq.set_vtt((void *) this);      
154         sp_ec_enable.set_vtt((void *) this);    
155         sp_ec_length.set_vtt((void *) this);
156         sp_ec_pan.set_vtt((void *) this);
157         sp_ec_volume.set_vtt((void *) this);
158         sp_ec_feedback.set_vtt((void *) this);          
159         sp_mute.set_vtt((void *) this);
160         sp_spin.set_vtt((void *) this);
161
162         x_par = &sp_speed;
163         y_par = &sp_lp_freq;
164         
165         lp_fx=new vtt_fx_lp();
166         lp_fx->set_vtt((void *) this);
167         fx_list.push_back(lp_fx);
168
169         ec_fx=new vtt_fx_ec();
170         ec_fx->set_vtt((void *) this);
171         fx_list.push_back(ec_fx);
172         
173         if (do_create_gui)
174         {       
175                 build_vtt_gui(this);
176                 lp_fx->set_panel_widget(gui.lp_panel->get_widget());    
177                 ec_fx->set_panel_widget(gui.ec_panel->get_widget());
178         }
179         else have_gui=0;
180                 
181         set_pan(0);     
182         set_master_volume(globals.volume);
183         set_output_buffer_size(samples_in_mix_buffer/2);
184         
185         audiofile = NULL;
186         mix_solo=0;
187         mix_mute=0;
188         res_mute=mute;
189         res_mute_old=0;
190         
191         audio_hidden=false;
192         control_hidden=false;\r
193 }
194
195 vtt_class :: ~vtt_class()
196 {
197         vtt_fx *effect;
198         stop();
199
200         main_list.remove(this);
201         if (audiofile) delete audiofile;
202         //if (buffer) free(buffer);
203         if (output_buffer) tX_freemem(output_buffer, "output_buffer", "vtt Destructor");
204         vtt_amount--;
205         
206         while (fx_list.size())
207         { 
208                 effect=(*fx_list.begin());
209                 fx_list.remove(effect);
210                 delete effect;
211         }
212         
213         delete_gui(this);
214 }
215
216 void vtt_class :: set_name(char *newname)
217 {
218         strcpy(name, newname);
219         gui_set_name(this, name);       
220 }
221
222 int vtt_class :: load_file(char *fname)
223 {
224         int res;
225         int was_playing=is_playing;
226         
227         if (is_playing) stop();
228
229         if (audiofile) delete(audiofile);
230         
231         buffer=NULL;
232         samples_in_buffer=0;
233         maxpos=0;
234         strcpy(filename,"");
235
236         audiofile=new tx_audiofile();
237         res=audiofile->load(fname);     
238         
239         if (res==TX_AUDIO_SUCCESS)
240         {
241                 buffer=audiofile->get_buffer();
242                 samples_in_buffer=audiofile->get_no_samples();
243                 maxpos=audiofile->get_no_samples();
244                 strcpy(filename, fname);
245                 if (was_playing) trigger();
246 //              printf("Successfully loaded %s, %08x, %i\n", fname, buffer, samples_in_buffer);
247         }
248         
249         if (have_gui)
250         {
251                 gui_update_display(this);
252         }
253         ec_set_length(ec_length);
254         
255         return(res);
256 }
257
258 int vtt_class :: set_output_buffer_size(int newsize)
259 {
260         list <vtt_fx *> :: iterator effect;
261
262         if (ec_output_buffer) tX_freemem(ec_output_buffer, "ec_output_buffer", "vtt set_output_buffer_size()");
263         tX_malloc(ec_output_buffer, "ec_output_buffer", "vtt set_output_buffer_size()", sizeof(float)*newsize, (float *));
264
265         if (output_buffer) tX_freemem(output_buffer, "output_buffer", "vtt set_output_buffer_size()");
266         tX_malloc(output_buffer, "output_buffer", "vtt set_output_buffer_size()", sizeof(float)*newsize, (float *));
267
268         end_of_outputbuffer = output_buffer + newsize; //size_t(sizeof(float)*(newsize));
269         
270         samples_in_outputbuffer=newsize;
271         inv_samples_in_outputbuffer=1.0/samples_in_outputbuffer;
272
273         for (effect=fx_list.begin(); effect != fx_list.end(); effect++)
274         {
275                 (*effect)->reconnect_buffer();
276         }
277         
278         if (output_buffer) return(0);   
279         else return(0);
280 }
281
282 void vtt_class :: set_volume(f_prec newvol)
283 {
284         rel_volume=newvol;
285         recalc_volume();
286 }
287
288 void vtt_class :: recalc_volume()
289 {
290         res_volume=rel_volume*res_master_volume;
291         f_prec ec_res_volume=res_volume*ec_volume;
292         
293         if (pan>0.0)
294         {
295                 res_volume_left=(1.0-pan)*res_volume;
296                 res_volume_right=res_volume;
297         }
298         else if (pan<0.0)
299         {
300                 res_volume_left=res_volume;
301                 res_volume_right=(1.0+pan)*res_volume;
302         }
303         else
304         {
305                 res_volume_left=res_volume_right=res_volume;
306         }
307         
308         if (ec_pan>0.0)
309         {
310                 ec_volume_left=(1.0-ec_pan)*ec_res_volume;
311                 ec_volume_right=ec_res_volume;
312         }
313         else if (ec_pan<0.0)
314         {
315                 ec_volume_left=ec_res_volume;
316                 ec_volume_right=(1.0+ec_pan)*ec_res_volume;
317         }
318         else
319         {
320                 ec_volume_left=ec_volume_right=ec_res_volume;
321         }       
322 //      printf("vtt_volume: %f, %f, l: %f, r: %f\n", rel_volume, res_volume, res_volume_left, res_volume_right);
323         
324 #ifdef USE_3DNOW
325         mm_res_volume.s[0]=mm_res_volume.s[1]=res_volume;
326 #endif  
327 }
328
329 void vtt_class :: set_pan(f_prec newpan)
330 {
331         pan=newpan;
332         recalc_volume();
333 }
334
335 void vtt_class :: set_pitch(f_prec newpitch)
336 {
337         rel_pitch=newpitch;
338 //      res_pitch=fabs(globals.pitch)*rel_pitch;
339         res_pitch=globals.pitch*rel_pitch;
340         speed=res_pitch;
341         ec_set_length(ec_length);
342 }
343
344 void vtt_class :: recalc_pitch()
345 {
346 //      res_pitch=fabs(globals.pitch)*rel_pitch;
347         res_pitch=globals.pitch*rel_pitch;
348         speed=res_pitch;
349         ec_set_length(ec_length);
350 }
351
352 void vtt_class :: set_autotrigger(int newstate)
353 {
354         autotrigger=newstate;
355 }
356
357 void vtt_class :: set_loop(int newstate)
358 {
359         loop=newstate;
360 }
361
362 void vtt_class :: set_controls (int x, int y)
363 {
364         x_control=x;
365         y_control=y;
366 }
367
368 void vtt_class :: set_mute(int newstate)
369 {
370         mute=newstate;
371         calc_mute();
372 }
373
374 void vtt_class :: set_mix_mute(int newstate)
375 {
376         mix_mute=newstate;
377         calc_mute();
378 }
379
380 void vtt_class :: set_mix_solo(int newstate)
381 {
382         if (mix_solo && !newstate)
383         {
384                 /* turning it off */
385                 mix_solo=0;
386                 solo_ctr--;
387         }
388         else if (!mix_solo && newstate)
389         {
390                 /* turning it on */
391                 mix_solo=1;
392                 solo_ctr++;
393         }
394         calc_mute();
395
396         /* locking ? */
397         list <vtt_class *> :: iterator vtt;
398         
399         for (vtt=main_list.begin(); vtt!=main_list.end() ; vtt++)
400         {
401                 (*vtt)->calc_mute();
402         }
403 }
404
405 void vtt_class :: lp_set_enable (int newstate)
406 {
407         lp_enable=newstate;
408         lp_reset();
409 }
410
411 void vtt_class :: lp_reset()
412 {
413         lp_buf0=lp_buf1=0;
414 }
415
416 void vtt_class :: lp_set_gain (f_prec gain)
417 {
418         lp_gain=gain;
419         lp_resgain=lp_gain*lp_autogain;
420 }
421
422 void vtt_class :: lp_set_reso(f_prec reso)
423 {
424         lp_reso=reso;
425         
426         lp_b=reso*(1.0+(1.0/lp_a));
427         lp_autogain=1.0-reso*GAIN_AUTO_ADJUST;
428         lp_resgain=lp_gain*lp_autogain;
429 }
430
431 void vtt_class :: lp_set_freq(f_prec freq)
432 {
433         lp_freq=freq;
434         
435         lp_a=0.9999-freq;
436         lp_b=lp_reso*(1.0+(1.0/lp_a));
437 }
438
439 void vtt_class :: lp_setup(f_prec gain, f_prec reso, f_prec freq)
440 {
441         lp_freq=freq;
442         lp_reso=reso;
443         
444         lp_a=1.0-freq;
445         lp_b=reso*(1.0+(1.0/lp_a));
446         
447         lp_autogain=1.0-reso*GAIN_AUTO_ADJUST;
448         lp_resgain=lp_gain*lp_autogain;
449 }
450
451 void vtt_class :: ec_set_enable(int newstate)
452 {
453         ec_enable=newstate;
454         ec_clear_buffer();
455 }
456
457
458 void vtt_class :: ec_set_pan(f_prec pan)
459 {
460         ec_pan=pan;
461
462         recalc_volume();
463 }
464
465 /* Max length is 1.0 */
466
467 void vtt_class :: ec_set_length(f_prec length)
468 {
469         int delay;
470         int i=0;
471         
472         ec_length=length;
473         if (res_pitch==0) 
474         {
475                 ec_res_length=length*samples_in_buffer;
476         }
477         else
478         {
479                 ec_res_length=length*samples_in_buffer/res_pitch;       
480         }
481         
482         if (ec_res_length<0) ec_res_length*=-1;
483         
484         if (ec_res_length>=EC_MAX_BUFFER)
485         {
486                 ec_res_length=EC_MAX_BUFFER*length;
487         }
488         
489         delay=(int )floor(ec_res_length);
490         delay-=2;
491         ec_delay=&ec_buffer[delay];
492 }
493
494 void vtt_class :: ec_set_feedback(f_prec feedback)
495 {
496         ec_feedback=feedback;
497 }
498
499
500 void vtt_class :: ec_set_volume(f_prec volume)
501 {
502         ec_volume=volume;
503         recalc_volume();
504 }
505
506 void vtt_class :: ec_clear_buffer()
507 {
508         f_prec *ptr;
509         
510         for (ptr=ec_buffer; ptr<=ec_delay; ptr++)
511         {
512                 *ptr=0.0;
513         }
514         ec_ptr=ec_buffer;
515 }
516
517 void vtt_class :: render()
518 {
519         list <vtt_fx *> :: iterator effect;
520
521         if (do_scratch)
522         {
523                 if (sense_cycles>0)
524                 {
525                         sense_cycles--;
526                         if (sense_cycles==0) sp_speed.receive_input_value(0);
527                 }
528         }
529         render_scratch();
530         
531         for (effect=fx_list.begin(); effect != fx_list.end(); effect++)
532         {
533                 if ((*effect)->isEnabled()) (*effect)->run();
534         }
535 }
536
537 extern void vg_create_fx_gui(vtt_class *vtt, vtt_fx_ladspa *effect, LADSPA_Plugin *plugin);
538
539 vtt_fx_ladspa * vtt_class :: add_effect (LADSPA_Plugin *plugin)
540 {
541         vtt_fx_ladspa *new_effect;
542         
543         new_effect = new vtt_fx_ladspa (plugin, this);
544         pthread_mutex_lock(&render_lock);
545         fx_list.push_back(new_effect);
546         if (is_playing) new_effect->activate();
547         pthread_mutex_unlock(&render_lock);
548         vg_create_fx_gui(this, new_effect, plugin);
549         
550         return new_effect;
551 }
552
553 void vtt_class :: calc_speed()
554 {
555         do_mute=fade_out=fade_in=0;
556
557         if (speed != speed_target)
558         {
559                 speed_target=speed;
560                 speed_step=speed_target-speed_real;
561                 speed_step/=10.0;
562         }
563                         
564         if (speed_target != speed_real)
565         {
566                 speed_real+=speed_step;
567                 if ((speed_step<0) && (speed_real<speed_target)) speed_real=speed_target;
568                 else
569                 if ((speed_step>0) && (speed_real>speed_target)) speed_real=speed_target;                       
570         }
571         
572         if (fade)
573         {
574                 if ((speed_last==0) && (speed_real !=0))
575                 {
576                         fade_in=1;
577                         fade=NEED_FADE_OUT;
578                 }
579         }
580         else
581         {
582                 if ((speed_last!=0) && (speed_real==0))
583                 {
584                         fade_out=1;
585                         fade=NEED_FADE_IN;
586                 }
587         }
588
589         speed_last = speed_real;
590
591         if (res_mute != res_mute_old)
592         {
593                 if (res_mute)
594                 {
595                         fade_out=1; fade_in=0;
596                         fade=NEED_FADE_IN;
597                 }
598                 else
599                 {
600                         fade_in=1; fade_out=0;
601                         fade=NEED_FADE_OUT;
602                 }
603                 res_mute_old=res_mute;
604         }
605         else
606         {
607                 if (res_mute) do_mute=1;
608         }       
609 }
610
611 void vtt_class :: render_scratch()
612 {
613         int16_t *ptr;
614         
615         int sample;
616         
617         f_prec pos_a_f;
618         
619         f_prec amount_a;
620         f_prec amount_b;
621
622         f_prec sample_a;
623         f_prec sample_b;
624         
625         f_prec sample_res;
626         
627         f_prec *out;
628         f_prec fade_vol;        
629
630         calc_speed();
631                                         
632         for (sample =0,out=output_buffer, fade_vol=0.0; sample < samples_in_outputbuffer;sample++, out++, fade_vol+=inv_samples_in_outputbuffer)
633         {
634                 if ((speed_real!=0) || (fade_out))
635                 {
636
637                         pos_f+=speed_real;
638
639                         if (pos_f>maxpos)
640                         {
641                                 pos_f-=maxpos;
642                                 if (res_pitch>0)
643                                 {
644                                         if (loop)
645                                         {
646                                         if (is_sync_master)
647                                         {
648                                                 master_triggered=1;
649                                                 master_triggered_at=sample;
650                                         }
651                                         }
652                                         else
653                                         {
654                                                 want_stop=1;
655                                         }
656                                         
657                                 }
658                         }
659                         else if (pos_f<0)
660                         {
661                                 pos_f+=maxpos;
662                                 if (res_pitch<0)
663                                 {
664                                         if (loop)
665                                         {
666                                         if (is_sync_master)
667                                         {
668                                                 master_triggered=1;
669                                                 master_triggered_at=sample;
670                                         }
671                                         }
672                                         else
673                                         {
674                                                 want_stop=1;
675                                         }
676                                 }
677                         }
678                                 
679                         pos_a_f=floor(pos_f);
680                         pos_i=(unsigned int) pos_a_f;
681                                                                 
682                         amount_b=pos_f-pos_a_f;                         
683                         amount_a=1.0-amount_b;                          
684                                 
685                         if (do_mute)
686                         {
687                                 *out=0.0;
688                         }
689                         else
690                         {
691                                 ptr=&buffer[pos_i];
692                                 sample_a=(f_prec) *ptr;
693                         
694                                 if (pos_i == samples_in_buffer) 
695                                 {
696                                         sample_b=*buffer;
697                                 }
698                                 else
699                                 {
700                                         ptr++;
701                                         sample_b=(f_prec) *ptr;
702                                 }
703                                 
704                                 sample_res=(sample_a*amount_a)+(sample_b*amount_b);
705                                                                 
706                                 if (fade_in)
707                                 {
708                                         sample_res*=fade_vol;
709                                 }
710                                 else
711                                 if (fade_out)
712                                 {
713                                         sample_res*=1.0-fade_vol;
714                                 }
715  
716                                 *out=sample_res;
717                         }
718                 }
719                 else
720                 {
721                                 *out=0;
722                 }
723         }
724 }       
725
726 void vtt_class :: forward_turntable()
727 {
728         int sample;
729         double pos_f_tmp;
730 #ifdef pos_f_test
731         int show=0;
732         double diff;
733 #endif
734
735         calc_speed();
736
737         if ((speed_real==0) && (!fade_out)) return;
738         
739         
740         /* following code is problematic as adding speed_real*n is
741           different from adding speed_real n times to pos_f.
742           
743           well it speeds things up quite a bit and double precision
744           seems to do a satisfying job.
745           
746           #define pos_f_test to prove that.
747         */
748         
749         pos_f_tmp=pos_f+speed_real*samples_in_outputbuffer;
750         
751         if ((pos_f_tmp > 0) && (pos_f_tmp < maxpos))
752         {
753 #ifdef pos_f_test
754                 show=1;
755 #else   
756                 pos_f=pos_f_tmp;
757                 return;
758 #endif          
759         }
760                                 
761         /* now the slow way ;) */
762         
763         for (sample =0; sample < samples_in_outputbuffer; sample++)
764         {
765                         pos_f+=speed_real;
766
767                         if (pos_f>maxpos)
768                         {
769                                 pos_f-=maxpos;
770                                 if (res_pitch>0)
771                                 {
772                                         if (loop)
773                                         {
774                                         if (is_sync_master)
775                                         {
776                                                 master_triggered=1;
777                                                 master_triggered_at=sample;
778                                         }
779                                         }
780                                         else
781                                         {
782                                                 want_stop=1;
783                                         }
784                                         
785                                 }
786                         }
787                         else if (pos_f<0)
788                         {
789                                 pos_f+=maxpos;
790                                 if (res_pitch<0)
791                                 {
792                                         if (loop)
793                                         {
794                                         if (is_sync_master)
795                                         {
796                                                 master_triggered=1;
797                                                 master_triggered_at=sample;
798                                         }
799                                         }
800                                         else
801                                         {
802                                                 want_stop=1;
803                                         }
804                                 }
805                         }
806                 
807         }
808 #ifdef pos_f_test
809         if (show)
810         {
811                 diff=pos_f_tmp-pos_f;
812                 if (diff!=0) printf("fast: %f, slow: %f, diff: %f, tt: %s\n", pos_f_tmp, pos_f, diff, name);
813         }
814 #endif  
815 }       
816
817 /*
818         The following lowpass filter is based on some sample code by
819         Paul Kellett <paul.kellett@maxim.abel.co.uk>
820 */
821
822 void vtt_class :: render_lp()
823 {
824         f_prec *sample;
825                 
826         for (sample = output_buffer; sample<end_of_outputbuffer; sample++)
827         {
828                 lp_buf0 = lp_a * lp_buf0 + lp_freq * ((*sample)*lp_resgain + lp_b * (lp_buf0 - lp_buf1));
829                 lp_buf1 = lp_a * lp_buf1 + lp_freq * lp_buf0;
830                 
831                 *sample=lp_buf1;
832         }
833 }
834
835 void vtt_class :: render_ec()
836 {
837         f_prec *sample;
838         f_prec *ec_sample;
839         int i;
840
841         for (i=0, sample = output_buffer, ec_sample=ec_output_buffer; i<samples_in_outputbuffer; i++, ec_sample++,sample++, ec_ptr++)
842         {
843                 if (ec_ptr>ec_delay) ec_ptr=ec_buffer;
844                 *ec_sample=(*ec_ptr) *ec_feedback;
845                 *ec_ptr=*sample+*ec_sample;
846         }       
847 }
848
849 int vtt_class :: set_mix_buffer_size(int no_samples)
850 {
851         list <vtt_class *> :: iterator vtt;
852         int res=0;
853         
854 //      printf("vtt_class::set_mix_buffer_size(), mix_buffer: %12x, mix_out: %12x, samples: %i\n", mix_buffer, mix_out_buffer, no_samples);
855         
856         if (mix_buffer) tX_freemem(mix_buffer, "mix_buffer", "vtt set_mix_buffer_size()");
857         samples_in_mix_buffer=no_samples*2;
858
859         tX_malloc(mix_buffer, "mix_buffer", "vtt set_mix_buffer_size()", sizeof(float)*samples_in_mix_buffer, (float *));
860         mix_buffer_end=mix_buffer+samples_in_mix_buffer;
861
862 //      printf("mix_buffer: %12x\n", mix_buffer);
863 //      printf("mix_samples: %i, out_samples: %i", samples_in_mix_buffer, no_samples);
864         
865         if (mix_out_buffer) tX_freemem(mix_out_buffer, "mix_out_buffer", "vtt set_mix_buffer_size()");
866         tX_malloc(mix_out_buffer, "mix_out_buffer", "vtt set_mix_buffer_size()", sizeof(int16_t)*samples_in_mix_buffer + 4, (int16_t *));
867
868 //      printf("mix_out_buffer: %12x\n", mix_out_buffer);
869         
870         for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
871         {
872                 res|=(*vtt)->set_output_buffer_size(no_samples);
873         }
874         
875         if ((!mix_buffer) || (!mix_out_buffer) || res) return(1);
876         return(0);
877 }
878
879 int16_t * vtt_class :: render_all_turntables()
880 {
881         list <vtt_class *> :: iterator vtt, next;
882         int sample;
883         int mix_sample;
884         f_prec temp;
885
886 #ifdef USE_3DNOW
887         mmx_t *mix;
888         mmx_t *vtt_buffer;
889         int32_t *mix_int;
890 #endif
891
892 #ifdef USE_FLASH
893         f_prec max;
894         f_prec min;
895 #ifdef USE_3DNOW
896         mmx_t mm_max;
897         mmx_t mm_min;
898         mmx_t mm_volume;
899         mmx_t mm_src1;
900         mmx_t mm_src2;
901
902 #ifndef OVERRIDE_MOVQ_AUTODETECT
903 #ifndef GCC_VERSION
904 #define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
905 #endif /* GCC_VERSION */
906
907 #if (GCC_VERSION < 2096)
908 #warning "*************************"
909 #warning "* gcc < 2.96            *"
910 #warning "* assuming working movq *"
911 #warning "*************************"
912 #undef GCC_MOVQ_BUG_WORKAROUND
913 #else
914 #warning "*************************"
915 #warning "* gcc >= 2.96           *"
916 #warning "* using movq-workaround *"
917 #warning "*************************"
918 #define GCC_MOVQ_BUG_WORKAROUND 1
919 #endif /* GCC < 2.96 */
920 #endif /* OVERRIDE MOVQ AUTODETECVT */
921         
922 #ifdef GCC_MOVQ_BUG_WORKAROUND
923         /* REQUIRED DUE TO GCC BUG (2.96-3.0.2) */
924         mmx_t *mm_src1_ptr=&mm_src1;
925         mmx_t *mm_src2_ptr=&mm_src2;
926         mmx_t *mm_volume_ptr=&mm_volume;
927         mmx_t *mm_max_ptr=&mm_max;
928         mmx_t *mm_min_ptr=&mm_min;
929         
930 #define MM_VAR_ACC(var) (* var ## _ptr)
931 #define MM_VAR_MOVQ(var) * var ## _ptr
932 #else
933 #define MM_VAR_ACC(var) var
934 #define MM_VAR_MOVQ(var) var
935 #endif  
936         int32_t *temp_int=&mm_max.d[1];
937 #endif  
938 #endif  
939         
940         pthread_mutex_lock(&render_lock);
941         
942         if (render_list.size()==0)
943         {
944                 for (sample=0; sample<samples_in_mix_buffer; sample++)
945                 {
946                         mix_out_buffer[sample]=0;
947                 }
948         }
949         else
950         {
951                         vtt=render_list.begin();
952                         (*vtt)->render();                       
953                         max=(*vtt)->max_value;
954                         min=max;
955
956 #ifndef USE_3DNOW
957                         for (sample=0, mix_sample=0; sample<(*vtt)->samples_in_outputbuffer; sample++)
958                         {                               
959                                 temp=(*vtt)->output_buffer[sample];
960                                 mix_buffer[mix_sample]=temp*(*vtt)->res_volume_left;
961                                 mix_sample++;
962                                 mix_buffer[mix_sample]=temp*(*vtt)->res_volume_right;
963                                 mix_sample++;
964                                 
965                                 if (temp>max) max=temp;
966                                 else if (temp<min) min=temp;
967                         }
968 #else
969                         MM_VAR_ACC(mm_volume).s[0]=(*vtt)->res_volume_left;
970                         MM_VAR_ACC(mm_volume).s[1]=(*vtt)->res_volume_right;
971
972                         MM_VAR_ACC(mm_max).s[1]=MM_VAR_ACC(mm_max).s[0]=max;
973                         MM_VAR_ACC(mm_min).s[1]=MM_VAR_ACC(mm_min).s[0]=min;
974                         
975                         movq_m2r(MM_VAR_MOVQ(mm_max), mm1);
976                         movq_m2r(MM_VAR_MOVQ(mm_min), mm2);
977                                                         
978                         movq_m2r(MM_VAR_MOVQ(mm_volume), mm0);
979                         
980                         mix=(mmx_t*)mix_buffer;
981                         
982                         for (f_prec* src=(*vtt)->output_buffer; mix < (mmx_t*) mix_buffer_end;)
983                         {
984                                 /* first sample */
985                                 MM_VAR_ACC(mm_src1).s[0]=*src;
986                                 MM_VAR_ACC(mm_src1).s[1]=*src;
987                                         
988                                 /* sample * l/r volume */
989                                 movq_m2r(MM_VAR_MOVQ(mm_src1), mm3);
990                                 pfmul_r2r(mm0, mm3);
991                                 movq_r2m(mm3, *mix);
992                                         
993                                 /* next sample */
994                                 src++, mix++;
995                                 MM_VAR_ACC(mm_src2).s[0]=*src;
996                                 MM_VAR_ACC(mm_src2).s[1]=*src;
997                                         
998                                 /* sample * l/r volume */
999                                 movq_m2r(MM_VAR_MOVQ(mm_src2), mm3);
1000                                 pfmul_r2r(mm0, mm3);
1001                                 movq_r2m(mm3, *mix);
1002                                         
1003                                 /* calculating min/max */
1004                                 MM_VAR_ACC(mm_src1).s[1]=MM_VAR_ACC(mm_src2).s[0];
1005                                 movq_m2r(mm_src1, mm3);
1006                                 pfmax_r2r(mm3, mm1);
1007                                 pfmin_r2r(mm3, mm2);
1008                                 
1009                                 src++, mix++;
1010                         }
1011
1012                         movq_r2m(mm1, MM_VAR_MOVQ(mm_max));
1013                         movq_r2m(mm2, MM_VAR_MOVQ(mm_min));
1014                         
1015                         femms();
1016                         
1017                         if (MM_VAR_ACC(mm_max).s[0]>MM_VAR_ACC(mm_max).s[1]) max=MM_VAR_ACC(mm_max).s[0]; else max=MM_VAR_ACC(mm_max).s[1];
1018                         if (MM_VAR_ACC(mm_min).s[0]<MM_VAR_ACC(mm_min).s[0]) min=MM_VAR_ACC(mm_min).s[0]; else min=MM_VAR_ACC(mm_min).s[1];
1019 #endif                  
1020                         
1021                         min*=-1.0;
1022                         if (min>max) (*vtt)->max_value=min; else (*vtt)->max_value=max;
1023
1024                         if ((*vtt)->ec_enable)
1025                         {
1026 #ifndef USE_3DNOW                       
1027                                 for (sample=0, mix_sample=0; sample<(*vtt)->samples_in_outputbuffer; sample++)
1028                                 {                               
1029                                         temp=(*vtt)->ec_output_buffer[sample];
1030                                         
1031                                         mix_buffer[mix_sample]+=temp*(*vtt)->ec_volume_left;
1032                                         mix_sample++;
1033                                         mix_buffer[mix_sample]+=temp*(*vtt)->ec_volume_right;
1034                                         mix_sample++;
1035                                 }
1036 #else
1037                                 MM_VAR_ACC(mm_volume).s[0]=(*vtt)->ec_volume_left;
1038                                 MM_VAR_ACC(mm_volume).s[1]=(*vtt)->ec_volume_right;
1039                                                 
1040                                 movq_m2r(MM_VAR_MOVQ(mm_volume), mm0);
1041                                 mix =(mmx_t*)mix_buffer;
1042
1043                                 for (f_prec* src=(*vtt)->ec_output_buffer; mix < (mmx_t*) mix_buffer_end; src++, mix++)
1044                                 {
1045                                         /* first sample */
1046                                         MM_VAR_ACC(mm_src1).s[0]=*src;
1047                                         MM_VAR_ACC(mm_src1).s[1]=*src;
1048                                 
1049                                         /* sample * l/r volume */
1050                                         movq_m2r(MM_VAR_MOVQ(mm_src1), mm3);
1051                                         pfmul_r2r(mm0, mm3);
1052                                 
1053                                         /* accumulating complete mix */
1054                                         movq_m2r(*mix, mm4);
1055                                         pfadd_r2r(mm4, mm3);
1056                                         movq_r2m(mm3, *mix);
1057                                 }
1058                                 femms();
1059 #endif                          
1060                         }
1061                         
1062                         if (master_triggered)
1063                         {
1064                                 pthread_mutex_unlock(&render_lock);
1065                                 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
1066                                 {
1067                                         if ((*vtt)->is_sync_client)
1068                                         {
1069                                                 if ((*vtt)->sync_countdown)
1070                                                 {
1071                                                         (*vtt)->sync_countdown--;
1072                                                 }
1073                                                 else
1074                                                 {
1075                                                         (*vtt)->sync_countdown=(*vtt)->sync_cycles;
1076                                                         (*vtt)->trigger();
1077                                                 }
1078                                         }
1079                                 }
1080                                 pthread_mutex_lock(&render_lock);
1081                         }
1082                         
1083                         vtt=render_list.begin();
1084                         for (vtt++; vtt!=render_list.end(); vtt++)
1085                         {
1086                                 (*vtt)->render();                                       
1087                                 max=(*vtt)->max_value;
1088                                 min=max;
1089
1090 #ifndef USE_3DNOW
1091                                 for (sample=0, mix_sample=0; sample<(*vtt)->samples_in_outputbuffer; sample++)
1092                                 {                               
1093                                         temp=(*vtt)->output_buffer[sample];
1094                                         mix_buffer[mix_sample]+=temp*(*vtt)->res_volume_left;
1095                                         mix_sample++;                                   
1096                                         mix_buffer[mix_sample]+=temp*(*vtt)->res_volume_right;
1097                                         mix_sample++;
1098                                 
1099                                         if (temp>max) max=temp;
1100                                         else if (temp<min) min=temp;
1101                                 }
1102 #else
1103                                 MM_VAR_ACC(mm_volume).s[0]=(*vtt)->res_volume_left;
1104                                 MM_VAR_ACC(mm_volume).s[1]=(*vtt)->res_volume_right;
1105
1106                                 MM_VAR_ACC(mm_max).s[1]=MM_VAR_ACC(mm_max).s[0]=max;
1107                                 MM_VAR_ACC(mm_min).s[1]=MM_VAR_ACC(mm_min).s[0]=min;
1108                         
1109                                 movq_m2r(MM_VAR_MOVQ(mm_max), mm1);
1110                                 movq_m2r(MM_VAR_MOVQ(mm_min), mm2);
1111                                                         
1112                                 movq_m2r(MM_VAR_MOVQ(mm_volume), mm0);
1113                                 mix=(mmx_t*)mix_buffer;
1114
1115                                 for (f_prec* src=(*vtt)->output_buffer; mix < (mmx_t*) mix_buffer_end;)
1116                                 {
1117                                         /* first sample */
1118                                         MM_VAR_ACC(mm_src1).s[0]=*src;
1119                                         MM_VAR_ACC(mm_src1).s[1]=*src;
1120                                         
1121                                         /* sample * l/r volume */
1122                                         movq_m2r(MM_VAR_MOVQ(mm_src1), mm3);
1123                                         pfmul_r2r(mm0, mm3);
1124                                         
1125                                         /* accumulating complete mix */
1126                                         movq_m2r(*mix, mm4);
1127                                         pfadd_r2r(mm4, mm3);
1128                                         movq_r2m(mm3, *mix);
1129                                         
1130                                         /* next sample */
1131                                         src++, mix++;
1132                                         MM_VAR_ACC(mm_src2).s[0]=*src;
1133                                         MM_VAR_ACC(mm_src2).s[1]=*src;
1134                                         
1135                                         /* sample * l/r volume */
1136                                         movq_m2r(MM_VAR_MOVQ(mm_src2), mm3);
1137                                         pfmul_r2r(mm0, mm3);
1138
1139                                         /* accumulating complete mix */
1140                                         movq_m2r(*mix, mm4);
1141                                         pfadd_r2r(mm4, mm3);
1142                                         movq_r2m(mm3, *mix);
1143                                         
1144                                         /* calculating min/max */
1145                                         MM_VAR_ACC(mm_src1).s[1]=MM_VAR_ACC(mm_src2).s[0];
1146                                         movq_m2r(MM_VAR_MOVQ(mm_src1), mm3);
1147                                         pfmax_r2r(mm3, mm1);
1148                                         pfmin_r2r(mm3, mm2);
1149                                         
1150                                         src++, mix++;
1151                                 }
1152
1153                                 movq_r2m(mm1, MM_VAR_MOVQ(mm_max));
1154                                 movq_r2m(mm2, MM_VAR_MOVQ(mm_min));
1155                                 
1156                                 femms();
1157         
1158                                 if (MM_VAR_ACC(mm_max).s[0]>MM_VAR_ACC(mm_max).s[1]) max=MM_VAR_ACC(mm_max).s[0]; else max=MM_VAR_ACC(mm_max).s[1];
1159                                 if (MM_VAR_ACC(mm_min).s[0]<MM_VAR_ACC(mm_min).s[0]) min=MM_VAR_ACC(mm_min).s[0]; else min=MM_VAR_ACC(mm_min).s[1];
1160 #endif
1161                                 
1162                                 min*=-1.0;
1163                                 if (min>max) (*vtt)->max_value=min; else (*vtt)->max_value=max;
1164                                 
1165                                 if ((*vtt)->ec_enable)
1166                                 {
1167 #ifndef USE_3DNOW
1168                                         for (sample=0, mix_sample=0; sample<(*vtt)->samples_in_outputbuffer; sample++)
1169                                         {                               
1170                                                 temp=(*vtt)->ec_output_buffer[sample];
1171                                                 
1172                                                 mix_buffer[mix_sample]+=temp*(*vtt)->ec_volume_left;
1173                                                 mix_sample++;
1174                                                 mix_buffer[mix_sample]+=temp*(*vtt)->ec_volume_right;
1175                                                 mix_sample++;
1176                                         }
1177 #else
1178                                         MM_VAR_ACC(mm_volume).s[0]=(*vtt)->ec_volume_left;
1179                                         MM_VAR_ACC(mm_volume).s[1]=(*vtt)->ec_volume_right;
1180                                                 
1181                                         movq_m2r(MM_VAR_MOVQ(mm_volume), mm0);
1182                                         mix =(mmx_t*)mix_buffer;
1183
1184                                         for (f_prec* src=(*vtt)->ec_output_buffer; mix < (mmx_t*) mix_buffer_end; src++, mix++)
1185                                         {
1186                                                 /* first sample */
1187                                                 MM_VAR_ACC(mm_src1).s[0]=*src;
1188                                                 MM_VAR_ACC(mm_src1).s[1]=*src;
1189                                 
1190                                                 /* sample * l/r volume */
1191                                                 movq_m2r(MM_VAR_MOVQ(mm_src1), mm3);
1192                                                 pfmul_r2r(mm0, mm3);
1193                                 
1194                                                 /* accumulating complete mix */
1195                                                 movq_m2r(*mix, mm4);
1196                                                 pfadd_r2r(mm4, mm3);
1197                                                 movq_r2m(mm3, *mix);
1198                                         }
1199
1200                                         femms();
1201 #endif                                  
1202                                 }
1203                         }
1204                         
1205                         /* left */
1206                         
1207                         max=mix_max_l;
1208                         min=max;
1209
1210                         for (sample=0; sample<samples_in_mix_buffer; sample+=2)
1211                         {                               
1212                                 temp=mix_buffer[sample];
1213                                 mix_out_buffer[sample]=(int16_t) temp;
1214                         
1215                                 if (temp>max) max=temp;
1216                                 else if (temp<min) min=temp;
1217                         }
1218                         
1219                         min*=-1.0;
1220                         if (min>max) mix_max_l=min; else mix_max_l=max;         
1221                         
1222                         /* right */
1223                         
1224                         max=mix_max_r;
1225                         min=max;
1226
1227                         for (sample=1; sample<samples_in_mix_buffer; sample+=2)
1228                         {                               
1229                                 temp=mix_buffer[sample];
1230                                 mix_out_buffer[sample]=(int16_t) temp;
1231                         
1232                                 if (temp>max) max=temp;
1233                                 else if (temp<min) min=temp;
1234                         }
1235                         
1236                         min*=-1.0;
1237                         if (min>max) mix_max_r=min; else mix_max_r=max;         
1238                         
1239         }
1240         master_triggered=0;
1241                 
1242         vtt=render_list.begin();
1243         while (vtt!=render_list.end())
1244         {
1245                 next=vtt;
1246                 next++;
1247                 
1248                 if ((*vtt)->want_stop) (*vtt)->stop_nolock();
1249                 vtt=next;
1250         }
1251         pthread_mutex_unlock(&render_lock);
1252         
1253         return(mix_out_buffer);
1254 }
1255
1256 void vtt_class :: forward_all_turntables()
1257 {
1258         list <vtt_class *> :: iterator vtt, next;
1259
1260         if (render_list.size()>0)
1261         {
1262                  vtt=render_list.begin();
1263                  (*vtt)->forward_turntable();                    
1264
1265                  if (master_triggered)
1266                  {
1267                          for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
1268                          {
1269                                  if ((*vtt)->is_sync_client)
1270                                  {
1271                                          if ((*vtt)->sync_countdown)
1272                                          {
1273                                                  (*vtt)->sync_countdown--;
1274                                          }
1275                                          else
1276                                          {
1277                                                  (*vtt)->sync_countdown=(*vtt)->sync_cycles;
1278                                                  (*vtt)->trigger();
1279                                          }
1280                                  }
1281                          }
1282                  }
1283
1284                  vtt=render_list.begin();
1285                  for (vtt++; vtt!=render_list.end(); vtt++)
1286                  {
1287                          (*vtt)->forward_turntable();
1288                  }
1289                  
1290         }
1291         master_triggered=0;
1292         vtt=render_list.begin();
1293         while (vtt!=render_list.end())
1294         {
1295                 next=vtt;
1296                 next++;
1297                 
1298                 if ((*vtt)->want_stop) (*vtt)->stop_nolock();
1299                 vtt=next;
1300         }
1301 }
1302
1303
1304 int vtt_class :: trigger()
1305 {
1306         list <vtt_fx *> :: iterator effect;
1307
1308         if (!buffer) return (1);
1309         
1310         if (!is_playing) pthread_mutex_lock(&render_lock);
1311         
1312         if (res_pitch>=0) pos_f=0;
1313         else pos_f=maxpos;
1314         fade=NEED_FADE_OUT;
1315         speed=res_pitch;
1316         speed_real=res_pitch;
1317         speed_target=res_pitch;
1318         want_stop=0;
1319
1320         /* activating plugins */
1321         for (effect=fx_list.begin(); effect != fx_list.end(); effect++)
1322         {
1323                 (*effect)->activate();
1324         }
1325
1326
1327 #ifdef USE_FLASH
1328         max_value=0;
1329 #endif
1330         
1331         if (is_sync_master)
1332         {
1333                 master_triggered=1;
1334                 master_triggered_at=0;
1335         }
1336         
1337         if (!is_playing)
1338         {
1339                 is_playing=1;
1340         
1341                 if (is_sync_master) 
1342                 {
1343                         render_list.push_front(this);           
1344                 }               
1345                 else
1346                 {
1347                         render_list.push_back(this);
1348                 }
1349                 pthread_mutex_unlock(&render_lock);
1350         }
1351         return(0);
1352 }
1353
1354 int vtt_class :: stop_nolock()
1355 {
1356         list <vtt_fx *> :: iterator effect;
1357
1358         if (!is_playing) 
1359         {
1360                 pthread_mutex_unlock(&render_lock);
1361                 return(1);
1362         }
1363         render_list.remove(this);
1364         want_stop=0;
1365
1366         is_playing=0;
1367
1368 #ifdef USE_FLASH
1369         max_value=0;
1370 #endif
1371         cleanup_vtt(this);
1372         sync_countdown=0;
1373         
1374         /* deactivating plugins */
1375         for (effect=fx_list.begin(); effect != fx_list.end(); effect++)
1376         {
1377                 (*effect)->deactivate();
1378         }
1379         
1380         return(0);
1381 }
1382
1383 int vtt_class :: stop()
1384 {
1385         int res;
1386         
1387         pthread_mutex_lock(&render_lock);
1388
1389         res=stop_nolock();
1390
1391         pthread_mutex_unlock(&render_lock);
1392
1393         return(res);
1394 }
1395
1396 void vtt_class :: set_sync_master(int master)
1397 {
1398         if (master)
1399         {
1400                 if (sync_master) sync_master->set_sync_master(0);
1401                 sync_master=this;
1402                 is_sync_master=1;
1403         }
1404         else
1405         {
1406                 if (sync_master==this) sync_master=0;
1407                 is_sync_master=0;
1408                 gui_clear_master_button(this);
1409         }
1410 }
1411
1412 void vtt_class :: set_sync_client(int slave, int cycles)
1413 {
1414         is_sync_client=slave;
1415         sync_cycles=cycles;
1416 //      sync_countdown=cycles; 
1417         sync_countdown=0;
1418 }
1419
1420 void vtt_class :: set_sync_client_ug(int slave, int cycles)
1421 {
1422         set_sync_client(slave, cycles);
1423 }
1424
1425 void vtt_class :: set_master_volume(f_prec new_volume)
1426 {
1427         list <vtt_class *> :: iterator vtt;
1428
1429         master_volume=new_volume;
1430         globals.volume=new_volume;
1431         
1432         if (main_list.size()>0)
1433         {
1434                 vol_channel_adjust=sqrt((f_prec) main_list.size());
1435                 res_master_volume=master_volume/vol_channel_adjust;             
1436         }
1437                 
1438         for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
1439         {
1440                 (*vtt)->recalc_volume();
1441         }
1442 }
1443
1444 void vtt_class :: set_master_pitch(f_prec new_pitch)
1445 {
1446         list <vtt_class *> :: iterator vtt;
1447         
1448         globals.pitch=new_pitch;
1449         for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
1450         {
1451                 (*vtt)->recalc_pitch();
1452         }
1453 }
1454
1455 void vtt_class :: enable_saturate (int newstate)
1456 {
1457         do_saturate=newstate;
1458 }
1459
1460 void vtt_class :: focus_no(int no)
1461 {
1462         list <vtt_class *> :: iterator vtt;
1463         int i;
1464
1465         for (i=0, vtt=main_list.begin(); vtt!=main_list.end(); vtt++, i++)
1466         {
1467                 if (i==no)
1468                 {
1469                         focused_vtt=(*vtt);
1470                 }
1471         }
1472 }
1473
1474 void vtt_class :: focus_next()
1475 {
1476         list <vtt_class *> :: iterator vtt;
1477         
1478         if (!focused_vtt)
1479         {
1480                 if (main_list.size())
1481                 {
1482                         focused_vtt=(*main_list.begin());
1483                 }
1484                 return;
1485         }
1486         
1487         for (vtt=main_list.begin(); vtt!=main_list.end() ; vtt++)
1488         {
1489                 if ((*vtt)==focused_vtt)
1490                 {
1491                         vtt++;
1492                         if (vtt==main_list.end())
1493                         {                       
1494                                 focused_vtt=(*main_list.begin());
1495                                 return;
1496                         }
1497                         else
1498                         {
1499                                 focused_vtt=(*vtt);
1500                                 return;
1501                         }
1502                 }
1503         }
1504         
1505         focused_vtt=(*main_list.begin());
1506 }
1507
1508 void vtt_class :: set_scratch(int newstate)
1509 {
1510         if (newstate)
1511         {
1512                 sp_spin.receive_input_value(0);
1513                 do_scratch=1;
1514                 sense_cycles=globals.sense_cycles;
1515         }
1516         else
1517         {
1518                 sp_spin.receive_input_value(1);
1519                 do_scratch=0;
1520         }
1521 }
1522
1523 #define MAGIC 0.05
1524
1525 void vtt_class :: handle_input(int control, f_prec value)
1526 {
1527         f_prec temp;
1528         
1529         switch (control)
1530         {
1531                 case CONTROL_SCRATCH:
1532                 if (do_scratch) sp_speed.receive_input_value(value*globals.mouse_speed);
1533                 sense_cycles=globals.sense_cycles;
1534                 break;
1535                 
1536                 case CONTROL_VOLUME:
1537                 temp=rel_volume+MAGIC*value*globals.mouse_speed;
1538                 if (temp>2.0) temp=2.0;
1539                 else if (temp<0) temp=0;
1540                 sp_volume.receive_input_value(temp);
1541                 break;
1542                 
1543                 case CONTROL_CUTOFF:
1544                 temp=lp_freq+MAGIC*value*globals.mouse_speed;
1545                 if (temp>0.99) temp=0.99;
1546                 else if (temp<0) temp=0;
1547                 sp_lp_freq.receive_input_value(temp);
1548                 break;
1549                 
1550                 case CONTROL_FEEDBACK:
1551                 temp=ec_feedback+MAGIC*value*globals.mouse_speed;
1552                 if (temp>1.0) temp=1.0;
1553                 else if (temp<0) temp=0;
1554                 sp_ec_feedback.receive_input_value(temp);
1555                 break;
1556         }
1557 }
1558
1559 void vtt_class :: unfocus()
1560 {
1561         focused_vtt=NULL;
1562 }
1563
1564 extern void vg_display_ycontrol(vtt_class *vtt);
1565 extern void vg_display_xcontrol(vtt_class *vtt);
1566
1567 void vtt_class :: set_x_input_parameter(tX_seqpar *sp)
1568 {
1569         x_par = sp;
1570         vg_display_xcontrol(this);
1571 }
1572
1573 void vtt_class :: set_y_input_parameter(tX_seqpar *sp)
1574 {
1575         y_par = sp;
1576         vg_display_ycontrol(this);
1577 }
1578
1579 void vtt_class :: xy_input(f_prec x_value, f_prec y_value)
1580 {
1581         if (x_par) x_par->handle_mouse_input(x_value*globals.mouse_speed);
1582         if (y_par) y_par->handle_mouse_input(y_value*globals.mouse_speed);
1583 }
1584
1585 #define store(data); if (fwrite((void *) &data, sizeof(data), 1, output)!=1) res+=1;
1586
1587 int  vtt_class :: save(FILE * output)
1588 {
1589         list <vtt_fx *> :: iterator effect;
1590
1591         int res=0;
1592         guint32 pid;
1593         int32_t counter;
1594         guint8 hidden;
1595         
1596         store(name);
1597         store(filename);
1598         store(is_sync_master);
1599         store(is_sync_client);
1600         store(sync_cycles);
1601         store(rel_volume);
1602         store(rel_pitch);
1603         
1604         store(autotrigger);
1605         store(loop);
1606         
1607         store(mute);
1608         store(pan);
1609         
1610         store(lp_enable);
1611         store(lp_gain);
1612         store(lp_reso);
1613         store(lp_freq);
1614         
1615         store(ec_enable);
1616         store(ec_length);
1617         store(ec_feedback);
1618         store(ec_pan);
1619         store(ec_volume);
1620         
1621         store(audio_hidden);
1622         store(control_hidden);
1623
1624         pid=sp_speed.get_persistence_id();
1625         store(pid);
1626         pid=sp_volume.get_persistence_id();
1627         store(pid);
1628         pid=sp_pitch.get_persistence_id();
1629         store(pid);
1630         pid=sp_trigger.get_persistence_id();
1631         store(pid);
1632         pid=sp_loop.get_persistence_id();
1633         store(pid);
1634         pid=sp_sync_client.get_persistence_id();
1635         store(pid);
1636         pid=sp_sync_cycles.get_persistence_id();
1637         store(pid);
1638         pid=sp_lp_enable.get_persistence_id();
1639         store(pid);
1640         pid=sp_lp_gain.get_persistence_id();
1641         store(pid);
1642         pid=sp_lp_reso.get_persistence_id();
1643         store(pid);
1644         pid=sp_lp_freq.get_persistence_id();
1645         store(pid);
1646         pid=sp_ec_enable.get_persistence_id();
1647         store(pid);
1648         pid=sp_ec_length.get_persistence_id();
1649         store(pid);
1650         pid=sp_ec_feedback.get_persistence_id();
1651         store(pid);
1652         pid=sp_ec_volume.get_persistence_id();
1653         store(pid);
1654         pid=sp_ec_pan.get_persistence_id();
1655         store(pid);
1656         pid=sp_mute.get_persistence_id();
1657         store(pid);
1658         pid=sp_spin.get_persistence_id();
1659         store(pid);
1660         pid=sp_pan.get_persistence_id();
1661         store(pid);
1662                 
1663         counter=fx_list.size();
1664         store(counter);
1665
1666         for (effect=fx_list.begin(); effect!=fx_list.end(); effect++)
1667         {
1668                 (*effect)->save(output);
1669         }
1670         
1671         if (x_par)
1672         {
1673                 pid=1;
1674                 store(pid);
1675                 pid=x_par->get_persistence_id();
1676                 store(pid);
1677         }
1678         else
1679         {
1680                 pid=0;
1681                 store(pid);
1682         }
1683
1684         if (y_par)
1685         {
1686                 pid=1;
1687                 store(pid);
1688                 pid=y_par->get_persistence_id();
1689                 store(pid);
1690         }
1691         else
1692         {
1693                 pid=0;
1694                 store(pid);
1695         }
1696                 
1697         hidden=gui.main_panel->is_hidden();
1698         store(hidden);
1699
1700         hidden=gui.trigger_panel->is_hidden();
1701         store(hidden);
1702
1703         hidden=gui.lp_panel->is_hidden();
1704         store(hidden);
1705
1706         hidden=gui.ec_panel->is_hidden();
1707         store(hidden);
1708         
1709         return(res);
1710 }
1711
1712 #define atload(data); if (fread((void *) &data, sizeof(data), 1, input)!=1) res+=1;
1713
1714 int vtt_class :: load_10(FILE * input)
1715 {
1716         int res=0;
1717         
1718         atload(name);
1719         atload(filename);
1720         atload(is_sync_master);
1721         atload(is_sync_client);
1722         atload(sync_cycles);
1723         atload(rel_volume);
1724         recalc_volume();
1725         atload(rel_pitch);
1726         recalc_pitch();
1727         
1728         atload(autotrigger);
1729         atload(loop);
1730         
1731         atload(mute);
1732         atload(x_control);
1733         atload(y_control);      
1734         
1735         atload(lp_enable);
1736         atload(lp_gain);
1737         atload(lp_reso);
1738         atload(lp_freq);
1739         lp_setup(lp_gain, lp_reso, lp_freq);
1740         
1741         atload(ec_enable);
1742         atload(ec_length);
1743         ec_set_length(ec_length);
1744         atload(ec_feedback);
1745         ec_set_feedback(ec_feedback);
1746         
1747         return(res);
1748 }
1749
1750
1751 int vtt_class :: load_11(FILE * input)
1752 {
1753         int res=0;
1754         guint32 pid;
1755         int32_t gui_page;
1756         
1757         atload(name);
1758         atload(filename);
1759         atload(is_sync_master);
1760         atload(is_sync_client);
1761         atload(sync_cycles);
1762         atload(rel_volume);
1763         recalc_volume();
1764         atload(rel_pitch);
1765         recalc_pitch();
1766         
1767         atload(autotrigger);
1768         atload(loop);
1769         
1770         atload(mute);
1771         atload(x_control);
1772         atload(y_control);      
1773         
1774         atload(lp_enable);
1775         atload(lp_gain);
1776         atload(lp_reso);
1777         atload(lp_freq);
1778         lp_setup(lp_gain, lp_reso, lp_freq);
1779         
1780         atload(ec_enable);
1781         atload(ec_length);
1782         ec_set_length(ec_length);
1783         atload(ec_feedback);
1784         ec_set_feedback(ec_feedback);
1785
1786         atload(pid);
1787         sp_speed.set_persistence_id(pid);
1788         atload(pid);
1789         sp_volume.set_persistence_id(pid);
1790         atload(pid);
1791         sp_pitch.set_persistence_id(pid);
1792         atload(pid);
1793         sp_trigger.set_persistence_id(pid);
1794         atload(pid);
1795         sp_loop.set_persistence_id(pid);
1796         atload(pid);
1797         sp_sync_client.set_persistence_id(pid);
1798         atload(pid);
1799         sp_sync_cycles.set_persistence_id(pid);
1800         atload(pid);
1801         sp_lp_enable.set_persistence_id(pid);
1802         atload(pid);
1803         sp_lp_gain.set_persistence_id(pid);
1804         atload(pid);
1805         sp_lp_reso.set_persistence_id(pid);
1806         atload(pid);
1807         sp_lp_freq.set_persistence_id(pid);
1808         atload(pid);
1809         sp_ec_enable.set_persistence_id(pid);
1810         atload(pid);
1811         sp_ec_length.set_persistence_id(pid);
1812         atload(pid);
1813         sp_ec_feedback.set_persistence_id(pid);
1814         atload(pid);
1815         sp_mute.set_persistence_id(pid);
1816         atload(pid);
1817         sp_spin.set_persistence_id(pid);
1818         
1819         atload(gui_page);
1820         
1821         return(res);
1822 }
1823
1824 int vtt_class :: load_12(FILE * input)
1825 {
1826         int res=0;
1827         guint32 pid;
1828         int32_t counter;
1829         int32_t type;
1830         long id;
1831         int i,t;
1832         LADSPA_Plugin *plugin;
1833         char buffer[256];
1834         vtt_fx_ladspa *ladspa_effect;
1835         guint8 hidden;
1836         
1837         atload(buffer);
1838         this->set_name(buffer);
1839         atload(filename);
1840         atload(is_sync_master);
1841         atload(is_sync_client);
1842         atload(sync_cycles);
1843         atload(rel_volume);
1844         recalc_volume();
1845         atload(rel_pitch);
1846         recalc_pitch();
1847         
1848         atload(autotrigger);
1849         atload(loop);
1850         
1851         atload(mute);
1852         
1853         atload(lp_enable);
1854         atload(lp_gain);
1855         atload(lp_reso);
1856         atload(lp_freq);
1857         lp_setup(lp_gain, lp_reso, lp_freq);
1858         
1859         atload(ec_enable);
1860         atload(ec_length);
1861         ec_set_length(ec_length);
1862         atload(ec_feedback);
1863         ec_set_feedback(ec_feedback);
1864
1865         atload(pid);
1866         sp_speed.set_persistence_id(pid);
1867         atload(pid);
1868         sp_volume.set_persistence_id(pid);
1869         atload(pid);
1870         sp_pitch.set_persistence_id(pid);
1871         atload(pid);
1872         sp_trigger.set_persistence_id(pid);
1873         atload(pid);
1874         sp_loop.set_persistence_id(pid);
1875         atload(pid);
1876         sp_sync_client.set_persistence_id(pid);
1877         atload(pid);
1878         sp_sync_cycles.set_persistence_id(pid);
1879         atload(pid);
1880         sp_lp_enable.set_persistence_id(pid);
1881         atload(pid);
1882         sp_lp_gain.set_persistence_id(pid);
1883         atload(pid);
1884         sp_lp_reso.set_persistence_id(pid);
1885         atload(pid);
1886         sp_lp_freq.set_persistence_id(pid);
1887         atload(pid);
1888         sp_ec_enable.set_persistence_id(pid);
1889         atload(pid);
1890         sp_ec_length.set_persistence_id(pid);
1891         atload(pid);
1892         sp_ec_feedback.set_persistence_id(pid);
1893         atload(pid);
1894         sp_mute.set_persistence_id(pid);
1895         atload(pid);
1896         sp_spin.set_persistence_id(pid);
1897                 
1898         atload(counter);
1899         
1900         for (i=0; i<counter; i++)
1901         {
1902                 atload(type);
1903                 switch(type)
1904                 {
1905                         case TX_FX_BUILTINCUTOFF:
1906                                 for (t=0; t<fx_list.size(); t++) effect_down(lp_fx);
1907                         break;
1908                         
1909                         case TX_FX_BUILTINECHO:
1910                                 for (t=0; t<fx_list.size(); t++) effect_down(ec_fx);
1911                         break;
1912                         
1913                         case TX_FX_LADSPA:
1914                                 atload(id);
1915                                 plugin=LADSPA_Plugin::getPluginByUniqueID(id);
1916                                 if (plugin)
1917                                 {
1918                                         ladspa_effect=add_effect(plugin);
1919                                         ladspa_effect->load(input);
1920                                 }
1921                                 else
1922                                 {
1923                                         sprintf(buffer,"Fatal Error: Couldn't find required plugin with ID [%i].", id);
1924                                         tx_note(buffer);
1925                                         res++;
1926                                 }
1927                         break;
1928                         
1929                         default:
1930                                 tx_note("Fatal Error loading set: unknown effect type!");
1931                                 res++;
1932                 }               
1933         }
1934
1935         atload(pid);
1936         
1937         if (pid)
1938         {
1939                 atload(pid);
1940                 set_x_input_parameter(tX_seqpar :: get_sp_by_persistence_id(pid));
1941         }
1942         else set_x_input_parameter(NULL);
1943         
1944         atload(pid);
1945         
1946         if (pid)
1947         {
1948                 atload(pid);
1949                 set_y_input_parameter(tX_seqpar :: get_sp_by_persistence_id(pid));
1950         }
1951         else set_y_input_parameter(NULL);
1952
1953         atload(hidden);
1954         gui.main_panel->hide(hidden);
1955
1956         atload(hidden);
1957         gui.trigger_panel->hide(hidden);
1958
1959         atload(hidden);
1960         gui.lp_panel->hide(hidden);
1961
1962         atload(hidden);
1963         gui.ec_panel->hide(hidden);
1964         
1965         return(res);
1966 }
1967
1968 int vtt_class :: load_13(FILE * input)
1969 {
1970         int res=0;
1971         guint32 pid;
1972         int32_t counter;
1973         int32_t type;
1974         long id;
1975         int i,t;
1976         LADSPA_Plugin *plugin;
1977         char buffer[256];
1978         vtt_fx_ladspa *ladspa_effect;
1979         guint8 hidden;
1980         
1981         atload(buffer);
1982         this->set_name(buffer);
1983         atload(filename);
1984         atload(is_sync_master);
1985         atload(is_sync_client);
1986         atload(sync_cycles);
1987         atload(rel_volume);
1988         atload(rel_pitch);
1989         recalc_pitch();
1990         
1991         atload(autotrigger);
1992         atload(loop);
1993         
1994         atload(mute);
1995         atload(pan);
1996         
1997         atload(lp_enable);
1998         atload(lp_gain);
1999         atload(lp_reso);
2000         atload(lp_freq);
2001         lp_setup(lp_gain, lp_reso, lp_freq);
2002         
2003         atload(ec_enable);
2004         atload(ec_length);
2005         ec_set_length(ec_length);
2006         atload(ec_feedback);
2007         ec_set_feedback(ec_feedback);
2008         atload(ec_pan);
2009         ec_set_pan(ec_pan);
2010         atload(ec_volume);
2011         ec_set_volume(ec_volume);
2012
2013         recalc_volume();
2014
2015         atload(pid);
2016         sp_speed.set_persistence_id(pid);
2017         atload(pid);
2018         sp_volume.set_persistence_id(pid);
2019         atload(pid);
2020         sp_pitch.set_persistence_id(pid);
2021         atload(pid);
2022         sp_trigger.set_persistence_id(pid);
2023         atload(pid);
2024         sp_loop.set_persistence_id(pid);
2025         atload(pid);
2026         sp_sync_client.set_persistence_id(pid);
2027         atload(pid);
2028         sp_sync_cycles.set_persistence_id(pid);
2029         atload(pid);
2030         sp_lp_enable.set_persistence_id(pid);
2031         atload(pid);
2032         sp_lp_gain.set_persistence_id(pid);
2033         atload(pid);
2034         sp_lp_reso.set_persistence_id(pid);
2035         atload(pid);
2036         sp_lp_freq.set_persistence_id(pid);
2037         atload(pid);
2038         sp_ec_enable.set_persistence_id(pid);
2039         atload(pid);
2040         sp_ec_length.set_persistence_id(pid);
2041         atload(pid);
2042         sp_ec_feedback.set_persistence_id(pid);
2043         atload(pid);
2044         sp_ec_volume.set_persistence_id(pid);
2045         atload(pid);
2046         sp_ec_pan.set_persistence_id(pid);
2047         atload(pid);
2048         sp_mute.set_persistence_id(pid);
2049         atload(pid);
2050         sp_spin.set_persistence_id(pid);
2051         atload(pid);
2052         sp_pan.set_persistence_id(pid);
2053                 
2054         atload(counter);
2055         
2056         for (i=0; i<counter; i++)
2057         {
2058                 atload(type);
2059                 switch(type)
2060                 {
2061                         case TX_FX_BUILTINCUTOFF:
2062                                 for (t=0; t<fx_list.size(); t++) effect_down(lp_fx);
2063                         break;
2064                         
2065                         case TX_FX_BUILTINECHO:
2066                                 for (t=0; t<fx_list.size(); t++) effect_down(ec_fx);
2067                         break;
2068                         
2069                         case TX_FX_LADSPA:
2070                                 atload(id);
2071                                 plugin=LADSPA_Plugin::getPluginByUniqueID(id);
2072                                 if (plugin)
2073                                 {
2074                                         ladspa_effect=add_effect(plugin);
2075                                         ladspa_effect->load(input);
2076                                 }
2077                                 else
2078                                 {
2079                                         sprintf(buffer,"Fatal Error: Couldn't find required plugin with ID [%i].", id);
2080                                         tx_note(buffer);
2081                                         res++;
2082                                 }
2083                         break;
2084                         
2085                         default:
2086                                 tx_note("Fatal Error loading set: unknown effect type!");
2087                                 res++;
2088                 }               
2089         }
2090
2091         atload(pid);
2092         
2093         if (pid)
2094         {
2095                 atload(pid);
2096                 set_x_input_parameter(tX_seqpar :: get_sp_by_persistence_id(pid));
2097         }
2098         else set_x_input_parameter(NULL);
2099         
2100         atload(pid);
2101         
2102         if (pid)
2103         {
2104                 atload(pid);
2105                 set_y_input_parameter(tX_seqpar :: get_sp_by_persistence_id(pid));
2106         }
2107         else set_y_input_parameter(NULL);
2108
2109         atload(hidden);
2110         gui.main_panel->hide(hidden);
2111
2112         atload(hidden);
2113         gui.trigger_panel->hide(hidden);
2114
2115         atload(hidden);
2116         gui.lp_panel->hide(hidden);
2117
2118         atload(hidden);
2119         gui.ec_panel->hide(hidden);
2120         
2121         return(res);
2122 }
2123
2124 int vtt_class :: load_14(FILE * input)
2125 {
2126         int res=0;
2127         guint32 pid;
2128         int32_t counter;
2129         int32_t type;
2130         long id;
2131         int i,t;
2132         LADSPA_Plugin *plugin;
2133         char buffer[256];
2134         vtt_fx_ladspa *ladspa_effect;
2135         guint8 hidden;
2136         
2137         atload(buffer);
2138         this->set_name(buffer);
2139         atload(filename);
2140         atload(is_sync_master);
2141         atload(is_sync_client);
2142         atload(sync_cycles);
2143         atload(rel_volume);
2144         atload(rel_pitch);
2145         recalc_pitch();
2146         
2147         atload(autotrigger);
2148         atload(loop);
2149         
2150         atload(mute);
2151         atload(pan);
2152         
2153         atload(lp_enable);
2154         atload(lp_gain);
2155         atload(lp_reso);
2156         atload(lp_freq);
2157         lp_setup(lp_gain, lp_reso, lp_freq);
2158         
2159         atload(ec_enable);
2160         atload(ec_length);
2161         ec_set_length(ec_length);
2162         atload(ec_feedback);
2163         ec_set_feedback(ec_feedback);
2164         atload(ec_pan);
2165         ec_set_pan(ec_pan);
2166         atload(ec_volume);
2167         ec_set_volume(ec_volume);
2168
2169         atload(audio_hidden);
2170         hide_audio(audio_hidden);
2171         
2172         atload(control_hidden);
2173         hide_control(control_hidden);
2174         
2175         recalc_volume();
2176
2177         atload(pid);
2178         sp_speed.set_persistence_id(pid);
2179         atload(pid);
2180         sp_volume.set_persistence_id(pid);
2181         atload(pid);
2182         sp_pitch.set_persistence_id(pid);
2183         atload(pid);
2184         sp_trigger.set_persistence_id(pid);
2185         atload(pid);
2186         sp_loop.set_persistence_id(pid);
2187         atload(pid);
2188         sp_sync_client.set_persistence_id(pid);
2189         atload(pid);
2190         sp_sync_cycles.set_persistence_id(pid);
2191         atload(pid);
2192         sp_lp_enable.set_persistence_id(pid);
2193         atload(pid);
2194         sp_lp_gain.set_persistence_id(pid);
2195         atload(pid);
2196         sp_lp_reso.set_persistence_id(pid);
2197         atload(pid);
2198         sp_lp_freq.set_persistence_id(pid);
2199         atload(pid);
2200         sp_ec_enable.set_persistence_id(pid);
2201         atload(pid);
2202         sp_ec_length.set_persistence_id(pid);
2203         atload(pid);
2204         sp_ec_feedback.set_persistence_id(pid);
2205         atload(pid);
2206         sp_ec_volume.set_persistence_id(pid);
2207         atload(pid);
2208         sp_ec_pan.set_persistence_id(pid);
2209         atload(pid);
2210         sp_mute.set_persistence_id(pid);
2211         atload(pid);
2212         sp_spin.set_persistence_id(pid);
2213         atload(pid);
2214         sp_pan.set_persistence_id(pid);
2215                 
2216         atload(counter);
2217         
2218         for (i=0; i<counter; i++)
2219         {
2220                 atload(type);
2221                 switch(type)
2222                 {
2223                         case TX_FX_BUILTINCUTOFF:
2224                                 for (t=0; t<fx_list.size(); t++) effect_down(lp_fx);
2225                         break;
2226                         
2227                         case TX_FX_BUILTINECHO:
2228                                 for (t=0; t<fx_list.size(); t++) effect_down(ec_fx);
2229                         break;
2230                         
2231                         case TX_FX_LADSPA:
2232                                 atload(id);
2233                                 plugin=LADSPA_Plugin::getPluginByUniqueID(id);
2234                                 if (plugin)
2235                                 {
2236                                         ladspa_effect=add_effect(plugin);
2237                                         ladspa_effect->load(input);
2238                                 }
2239                                 else
2240                                 {
2241                                         sprintf(buffer,"Fatal Error: Couldn't find required plugin with ID [%i].", id);
2242                                         tx_note(buffer);
2243                                         res++;
2244                                 }
2245                         break;
2246                         
2247                         default:
2248                                 tx_note("Fatal Error loading set: unknown effect type!");
2249                                 res++;
2250                 }               
2251         }
2252
2253         atload(pid);
2254         
2255         if (pid)
2256         {
2257                 atload(pid);
2258                 set_x_input_parameter(tX_seqpar :: get_sp_by_persistence_id(pid));
2259         }
2260         else set_x_input_parameter(NULL);
2261         
2262         atload(pid);
2263         
2264         if (pid)
2265         {
2266                 atload(pid);
2267                 set_y_input_parameter(tX_seqpar :: get_sp_by_persistence_id(pid));
2268         }
2269         else set_y_input_parameter(NULL);
2270
2271         atload(hidden);
2272         gui.main_panel->hide(hidden);
2273
2274         atload(hidden);
2275         gui.trigger_panel->hide(hidden);
2276
2277         atload(hidden);
2278         gui.lp_panel->hide(hidden);
2279
2280         atload(hidden);
2281         gui.ec_panel->hide(hidden);
2282         
2283         return(res);
2284 }
2285
2286
2287 int  vtt_class :: save_all(FILE* output)
2288 {
2289         int res=0;
2290         list <vtt_class *> :: iterator vtt;
2291         guint32 pid;
2292         
2293         tX_seqpar :: create_persistence_ids();
2294         
2295         store(vtt_amount);
2296         store(master_volume);
2297         store(globals.pitch);
2298         pid=sp_master_volume.get_persistence_id();
2299         store(pid);
2300         pid=sp_master_pitch.get_persistence_id();
2301         store(pid);
2302
2303         for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
2304         {
2305                 res+=(*vtt)->save(output);
2306         }
2307         
2308         sequencer.save(output);
2309         
2310         return(res);
2311 }
2312
2313 int  vtt_class :: load_all_10(FILE* input, char *fname)
2314 {
2315         int res=0, restmp=0;
2316         list <vtt_class *> :: iterator vtt;
2317         unsigned int i, max, size;
2318         int16_t *newbuffer;
2319         vtt_class *newvtt;
2320         char ftmp[PATH_MAX];
2321         
2322         while (main_list.size())
2323         {
2324                 delete((*main_list.begin()));
2325         }
2326                 
2327         atload(max);
2328         atload(master_volume);
2329         set_master_volume(master_volume);
2330         globals.volume=master_volume;
2331         atload(globals.pitch);  
2332         set_master_pitch(globals.pitch);
2333
2334         ld_create_loaddlg(TX_LOADDLG_MODE_MULTI, max);
2335         ld_set_setname(fname);
2336
2337         for (i=0; i<max; i++)
2338         {
2339                 newvtt=new vtt_class(1);
2340                 res+=newvtt->load_10(input);
2341                 
2342                 if (strlen(newvtt->filename))
2343                 {
2344                         /* ftmp IS NECESSARY !!! */
2345                         strcpy(ftmp, newvtt->filename);
2346                         ld_set_filename(ftmp);
2347                         
2348                         //restmp=load_wav(newvtt->filename, &newbuffer, &size);
2349                         restmp=newvtt->load_file(ftmp);
2350                         res+=restmp;
2351                 }
2352                 gtk_box_pack_start(GTK_BOX(control_parent), newvtt->gui.control_box, TRUE, TRUE, 0);
2353                 gtk_box_pack_start(GTK_BOX(audio_parent), newvtt->gui.audio_box, TRUE, TRUE, 0);
2354         
2355         }
2356         
2357         sequencer.clear();
2358         
2359         ld_destroy();
2360         
2361         return(res);
2362 }
2363
2364
2365 int  vtt_class :: load_all_11(FILE* input, char *fname)
2366 {
2367         int res=0, restmp=0;
2368         list <vtt_class *> :: iterator vtt;
2369         unsigned int i, max, size;
2370         int16_t *newbuffer;
2371         vtt_class *newvtt;
2372         char ftmp[PATH_MAX];
2373         guint32 pid;
2374         
2375         while (main_list.size())
2376         {
2377                 delete((*main_list.begin()));
2378         }
2379                 
2380         atload(max);
2381         atload(master_volume);
2382         set_master_volume(master_volume);
2383         globals.volume=master_volume;
2384         atload(globals.pitch);  
2385         set_master_pitch(globals.pitch);
2386         atload(pid);
2387         sp_master_volume.set_persistence_id(pid);
2388         atload(pid);
2389         sp_master_pitch.set_persistence_id(pid);
2390
2391         ld_create_loaddlg(TX_LOADDLG_MODE_MULTI, max);
2392         ld_set_setname(fname);
2393
2394         for (i=0; i<max; i++)
2395         {
2396                 newvtt=new vtt_class(1);
2397                 res+=newvtt->load_11(input);
2398                 
2399                 if (strlen(newvtt->filename))
2400                 {
2401                         /* ftmp IS NECESSARY !!! */
2402                         strcpy(ftmp, newvtt->filename);
2403                         ld_set_filename(ftmp);
2404                         
2405                         //restmp=load_wav(newvtt->filename, &newbuffer, &size);
2406                         restmp=newvtt->load_file(ftmp);
2407                         res+=restmp;
2408                 }
2409                 gtk_box_pack_start(GTK_BOX(control_parent), newvtt->gui.control_box, TRUE, TRUE, 0);
2410                 gtk_box_pack_start(GTK_BOX(audio_parent), newvtt->gui.audio_box, TRUE, TRUE, 0);
2411                 
2412         }
2413         
2414         sequencer.load(input);
2415         
2416         ld_destroy();
2417         
2418         return(res);
2419 }
2420
2421
2422 int  vtt_class :: load_all_12(FILE* input, char *fname)
2423 {
2424         int res=0, restmp=0;
2425         list <vtt_class *> :: iterator vtt;
2426         unsigned int i, max, size;
2427         int16_t *newbuffer;
2428         vtt_class *newvtt;
2429         char ftmp[PATH_MAX];
2430         guint32 pid;
2431         
2432         while (main_list.size())
2433         {
2434                 delete((*main_list.begin()));
2435         }
2436                 
2437         atload(max);
2438         atload(master_volume);
2439         set_master_volume(master_volume);
2440         globals.volume=master_volume;
2441         atload(globals.pitch);  
2442         set_master_pitch(globals.pitch);
2443         atload(pid);
2444         sp_master_volume.set_persistence_id(pid);
2445         atload(pid);
2446         sp_master_pitch.set_persistence_id(pid);
2447
2448         ld_create_loaddlg(TX_LOADDLG_MODE_MULTI, max);
2449         ld_set_setname(fname);
2450
2451         for (i=0; i<max; i++)
2452         {
2453                 newvtt=new vtt_class(1);
2454                 res+=newvtt->load_12(input);
2455                 
2456                 if (strlen(newvtt->filename))
2457                 {
2458                         /* ftmp IS NECESSARY !!! */
2459                         strcpy(ftmp, newvtt->filename);
2460                         ld_set_filename(ftmp);
2461                         
2462                         //restmp=load_wav(newvtt->filename, &newbuffer, &size);
2463                         restmp=newvtt->load_file(ftmp);
2464                         res+=restmp;
2465                 }
2466                 gtk_box_pack_start(GTK_BOX(control_parent), newvtt->gui.control_box, TRUE, TRUE, 0);
2467                 gtk_box_pack_start(GTK_BOX(audio_parent), newvtt->gui.audio_box, TRUE, TRUE, 0);
2468                 
2469         }
2470         
2471         sequencer.load(input);
2472         
2473         ld_destroy();
2474         
2475         return(res);
2476 }
2477
2478 int  vtt_class :: load_all_13(FILE* input, char *fname)
2479 {
2480         int res=0, restmp=0;
2481         list <vtt_class *> :: iterator vtt;
2482         unsigned int i, max, size;
2483         int16_t *newbuffer;
2484         vtt_class *newvtt;
2485         char ftmp[PATH_MAX];
2486         guint32 pid;
2487         
2488         while (main_list.size())
2489         {
2490                 delete((*main_list.begin()));
2491         }
2492                 
2493         atload(max);
2494         atload(master_volume);
2495         set_master_volume(master_volume);
2496         globals.volume=master_volume;
2497         atload(globals.pitch);  
2498         set_master_pitch(globals.pitch);
2499         atload(pid);
2500         sp_master_volume.set_persistence_id(pid);
2501         atload(pid);
2502         sp_master_pitch.set_persistence_id(pid);
2503
2504         ld_create_loaddlg(TX_LOADDLG_MODE_MULTI, max);
2505         ld_set_setname(fname);
2506
2507         for (i=0; i<max; i++)
2508         {
2509                 newvtt=new vtt_class(1);
2510                 res+=newvtt->load_13(input);
2511                 
2512                 if (strlen(newvtt->filename))
2513                 {
2514                         /* ftmp IS NECESSARY !!! */
2515                         strcpy(ftmp, newvtt->filename);
2516                         ld_set_filename(ftmp);
2517                         
2518                         //restmp=load_wav(newvtt->filename, &newbuffer, &size);
2519                         restmp=newvtt->load_file(ftmp);
2520                         res+=restmp;
2521                 }
2522                 gtk_box_pack_start(GTK_BOX(control_parent), newvtt->gui.control_box, TRUE, TRUE, 0);
2523                 gtk_box_pack_start(GTK_BOX(audio_parent), newvtt->gui.audio_box, TRUE, TRUE, 0);
2524                 
2525         }
2526         
2527         sequencer.load(input);
2528         
2529         ld_destroy();
2530         
2531         return(res);
2532 }
2533
2534 int  vtt_class :: load_all_14(FILE* input, char *fname)
2535 {
2536         int res=0, restmp=0;
2537         list <vtt_class *> :: iterator vtt;
2538         unsigned int i, max, size;
2539         int16_t *newbuffer;
2540         vtt_class *newvtt;
2541         char ftmp[PATH_MAX];
2542         guint32 pid;
2543         
2544         while (main_list.size())
2545         {
2546                 delete((*main_list.begin()));
2547         }
2548                 
2549         atload(max);
2550         atload(master_volume);
2551         set_master_volume(master_volume);
2552         globals.volume=master_volume;
2553         atload(globals.pitch);  
2554         set_master_pitch(globals.pitch);
2555         atload(pid);
2556         sp_master_volume.set_persistence_id(pid);
2557         atload(pid);
2558         sp_master_pitch.set_persistence_id(pid);
2559
2560         ld_create_loaddlg(TX_LOADDLG_MODE_MULTI, max);
2561         ld_set_setname(fname);
2562
2563         for (i=0; i<max; i++)
2564         {
2565                 newvtt=new vtt_class(1);
2566                 res+=newvtt->load_14(input);
2567                 
2568                 if (strlen(newvtt->filename))
2569                 {
2570                         /* ftmp IS NECESSARY !!! */
2571                         strcpy(ftmp, newvtt->filename);
2572                         ld_set_filename(ftmp);
2573                         
2574                         //restmp=load_wav(newvtt->filename, &newbuffer, &size);
2575                         restmp=newvtt->load_file(ftmp);
2576                         res+=restmp;
2577                 }
2578                 gtk_box_pack_start(GTK_BOX(control_parent), newvtt->gui.control_box, TRUE, TRUE, 0);
2579                 gtk_box_pack_start(GTK_BOX(audio_parent), newvtt->gui.audio_box, TRUE, TRUE, 0);
2580                 
2581         }
2582         
2583         sequencer.load(input);
2584         
2585         ld_destroy();
2586         
2587         return(res);
2588 }
2589
2590
2591 void add_vtt(GtkWidget *ctrl, GtkWidget *audio, char *fn)
2592 {
2593         vtt_class *hmmpg;
2594         hmmpg = new vtt_class(1);
2595         gtk_box_pack_start(GTK_BOX(ctrl), hmmpg->gui.control_box, TRUE, TRUE, 0);
2596         gtk_box_pack_start(GTK_BOX(audio), hmmpg->gui.audio_box, TRUE, TRUE, 0);
2597         if (fn) hmmpg->load_file(fn);
2598 }
2599
2600 extern void vg_move_fx_panel_up(GtkWidget *wid, vtt_class *vtt);
2601 extern void vg_move_fx_panel_down(GtkWidget *wid, vtt_class *vtt);
2602
2603 //#define debug_fx_stack(); for (i=fx_list.begin(); i != fx_list.end(); i++) puts((*i)->get_info_string());
2604 #define debug_fx_stack();
2605
2606 void vtt_class :: effect_up(vtt_fx *effect)
2607 {
2608         list <vtt_fx *> :: iterator i;
2609         list <vtt_fx *> :: iterator previous;
2610         int ok=0;
2611         
2612         debug_fx_stack();
2613         
2614         if ((*fx_list.begin())==effect) return;
2615         
2616         for (previous=i=fx_list.begin(); i != fx_list.end(); i++)
2617         {
2618                 if ((*i) == effect)
2619                 {
2620                         ok=1;
2621                         break;
2622                 }
2623                 previous=i;
2624         }
2625         
2626         if (ok)
2627         {       
2628                 pthread_mutex_lock(&render_lock);
2629                 fx_list.remove(effect);
2630                 fx_list.insert(previous, effect);
2631                 pthread_mutex_unlock(&render_lock);
2632
2633                 vg_move_fx_panel_up(effect->get_panel_widget(), this);
2634         }
2635         
2636         debug_fx_stack();
2637 }
2638
2639 void vtt_class :: effect_down(vtt_fx *effect)
2640 {
2641         list <vtt_fx *> :: iterator i;
2642         int ok=0;
2643
2644         debug_fx_stack();
2645                 
2646         for (i=fx_list.begin(); i != fx_list.end(); i++)
2647         {
2648                 if ((*i) == effect)
2649                 {
2650                         ok=1;
2651                         break;
2652                 }
2653         }
2654         
2655         if ((ok) && (i!=fx_list.end()))
2656         {
2657                 i++;
2658                 if (i==fx_list.end()) return;
2659                 i++;
2660
2661                 pthread_mutex_lock(&render_lock);
2662                 fx_list.remove(effect);
2663                 
2664                 fx_list.insert(i, effect);
2665                 vg_move_fx_panel_down(effect->get_panel_widget(), this);
2666                 pthread_mutex_unlock(&render_lock);
2667         }
2668         
2669 debug_fx_stack();       
2670 }
2671
2672 void vtt_class ::  effect_remove(vtt_fx_ladspa *effect)
2673 {
2674         pthread_mutex_lock(&render_lock);
2675         fx_list.remove(effect);
2676         pthread_mutex_unlock(&render_lock);
2677         
2678         delete effect;
2679 }
2680
2681 extern void gui_hide_control_panel(vtt_class *vtt, bool hide);
2682 extern void gui_hide_audio_panel(vtt_class *vtt, bool hide);
2683
2684 void vtt_class :: hide_audio(bool hide) {
2685         audio_hidden=hide;
2686         gui_hide_audio_panel(this, hide);
2687 }
2688
2689 void vtt_class :: hide_control(bool hide) {
2690         control_hidden=hide;
2691         gui_hide_control_panel(this, hide);     
2692 }