New Menus, many fixes, one-click popup for gtk2. Drag
[terminatorX.git] / 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 void vtt_class :: set_x_input_parameter(tX_seqpar *sp)
1565 {
1566         x_par = sp;
1567 }
1568
1569 void vtt_class :: set_y_input_parameter(tX_seqpar *sp)
1570 {
1571         y_par = sp;
1572 }
1573
1574 void vtt_class :: xy_input(f_prec x_value, f_prec y_value)
1575 {
1576         if (x_par) x_par->handle_mouse_input(x_value*globals.mouse_speed);
1577         if (y_par) y_par->handle_mouse_input(y_value*globals.mouse_speed);
1578 }
1579
1580 #define store(data); if (fwrite((void *) &data, sizeof(data), 1, output)!=1) res+=1;
1581
1582 int  vtt_class :: save(FILE * output)
1583 {
1584         list <vtt_fx *> :: iterator effect;
1585
1586         int res=0;
1587         guint32 pid;
1588         int32_t counter;
1589         guint8 hidden;
1590         
1591         store(name);
1592         store(filename);
1593         store(is_sync_master);
1594         store(is_sync_client);
1595         store(sync_cycles);
1596         store(rel_volume);
1597         store(rel_pitch);
1598         
1599         store(autotrigger);
1600         store(loop);
1601         
1602         store(mute);
1603         store(pan);
1604         
1605         store(lp_enable);
1606         store(lp_gain);
1607         store(lp_reso);
1608         store(lp_freq);
1609         
1610         store(ec_enable);
1611         store(ec_length);
1612         store(ec_feedback);
1613         store(ec_pan);
1614         store(ec_volume);
1615         
1616         store(audio_hidden);
1617         store(control_hidden);
1618
1619         pid=sp_speed.get_persistence_id();
1620         store(pid);
1621         pid=sp_volume.get_persistence_id();
1622         store(pid);
1623         pid=sp_pitch.get_persistence_id();
1624         store(pid);
1625         pid=sp_trigger.get_persistence_id();
1626         store(pid);
1627         pid=sp_loop.get_persistence_id();
1628         store(pid);
1629         pid=sp_sync_client.get_persistence_id();
1630         store(pid);
1631         pid=sp_sync_cycles.get_persistence_id();
1632         store(pid);
1633         pid=sp_lp_enable.get_persistence_id();
1634         store(pid);
1635         pid=sp_lp_gain.get_persistence_id();
1636         store(pid);
1637         pid=sp_lp_reso.get_persistence_id();
1638         store(pid);
1639         pid=sp_lp_freq.get_persistence_id();
1640         store(pid);
1641         pid=sp_ec_enable.get_persistence_id();
1642         store(pid);
1643         pid=sp_ec_length.get_persistence_id();
1644         store(pid);
1645         pid=sp_ec_feedback.get_persistence_id();
1646         store(pid);
1647         pid=sp_ec_volume.get_persistence_id();
1648         store(pid);
1649         pid=sp_ec_pan.get_persistence_id();
1650         store(pid);
1651         pid=sp_mute.get_persistence_id();
1652         store(pid);
1653         pid=sp_spin.get_persistence_id();
1654         store(pid);
1655         pid=sp_pan.get_persistence_id();
1656         store(pid);
1657                 
1658         counter=fx_list.size();
1659         store(counter);
1660
1661         for (effect=fx_list.begin(); effect!=fx_list.end(); effect++)
1662         {
1663                 (*effect)->save(output);
1664         }
1665         
1666         if (x_par)
1667         {
1668                 pid=1;
1669                 store(pid);
1670                 pid=x_par->get_persistence_id();
1671                 store(pid);
1672         }
1673         else
1674         {
1675                 pid=0;
1676                 store(pid);
1677         }
1678
1679         if (y_par)
1680         {
1681                 pid=1;
1682                 store(pid);
1683                 pid=y_par->get_persistence_id();
1684                 store(pid);
1685         }
1686         else
1687         {
1688                 pid=0;
1689                 store(pid);
1690         }
1691                 
1692         hidden=gui.main_panel->is_hidden();
1693         store(hidden);
1694
1695         hidden=gui.trigger_panel->is_hidden();
1696         store(hidden);
1697
1698         hidden=gui.lp_panel->is_hidden();
1699         store(hidden);
1700
1701         hidden=gui.ec_panel->is_hidden();
1702         store(hidden);
1703         
1704         return(res);
1705 }
1706
1707 #define atload(data); if (fread((void *) &data, sizeof(data), 1, input)!=1) res+=1;
1708
1709 int vtt_class :: load_10(FILE * input)
1710 {
1711         int res=0;
1712         
1713         atload(name);
1714         atload(filename);
1715         atload(is_sync_master);
1716         atload(is_sync_client);
1717         atload(sync_cycles);
1718         atload(rel_volume);
1719         recalc_volume();
1720         atload(rel_pitch);
1721         recalc_pitch();
1722         
1723         atload(autotrigger);
1724         atload(loop);
1725         
1726         atload(mute);
1727         atload(x_control);
1728         atload(y_control);      
1729         
1730         atload(lp_enable);
1731         atload(lp_gain);
1732         atload(lp_reso);
1733         atload(lp_freq);
1734         lp_setup(lp_gain, lp_reso, lp_freq);
1735         
1736         atload(ec_enable);
1737         atload(ec_length);
1738         ec_set_length(ec_length);
1739         atload(ec_feedback);
1740         ec_set_feedback(ec_feedback);
1741         
1742         return(res);
1743 }
1744
1745
1746 int vtt_class :: load_11(FILE * input)
1747 {
1748         int res=0;
1749         guint32 pid;
1750         int32_t gui_page;
1751         
1752         atload(name);
1753         atload(filename);
1754         atload(is_sync_master);
1755         atload(is_sync_client);
1756         atload(sync_cycles);
1757         atload(rel_volume);
1758         recalc_volume();
1759         atload(rel_pitch);
1760         recalc_pitch();
1761         
1762         atload(autotrigger);
1763         atload(loop);
1764         
1765         atload(mute);
1766         atload(x_control);
1767         atload(y_control);      
1768         
1769         atload(lp_enable);
1770         atload(lp_gain);
1771         atload(lp_reso);
1772         atload(lp_freq);
1773         lp_setup(lp_gain, lp_reso, lp_freq);
1774         
1775         atload(ec_enable);
1776         atload(ec_length);
1777         ec_set_length(ec_length);
1778         atload(ec_feedback);
1779         ec_set_feedback(ec_feedback);
1780
1781         atload(pid);
1782         sp_speed.set_persistence_id(pid);
1783         atload(pid);
1784         sp_volume.set_persistence_id(pid);
1785         atload(pid);
1786         sp_pitch.set_persistence_id(pid);
1787         atload(pid);
1788         sp_trigger.set_persistence_id(pid);
1789         atload(pid);
1790         sp_loop.set_persistence_id(pid);
1791         atload(pid);
1792         sp_sync_client.set_persistence_id(pid);
1793         atload(pid);
1794         sp_sync_cycles.set_persistence_id(pid);
1795         atload(pid);
1796         sp_lp_enable.set_persistence_id(pid);
1797         atload(pid);
1798         sp_lp_gain.set_persistence_id(pid);
1799         atload(pid);
1800         sp_lp_reso.set_persistence_id(pid);
1801         atload(pid);
1802         sp_lp_freq.set_persistence_id(pid);
1803         atload(pid);
1804         sp_ec_enable.set_persistence_id(pid);
1805         atload(pid);
1806         sp_ec_length.set_persistence_id(pid);
1807         atload(pid);
1808         sp_ec_feedback.set_persistence_id(pid);
1809         atload(pid);
1810         sp_mute.set_persistence_id(pid);
1811         atload(pid);
1812         sp_spin.set_persistence_id(pid);
1813         
1814         atload(gui_page);
1815         
1816         return(res);
1817 }
1818
1819 int vtt_class :: load_12(FILE * input)
1820 {
1821         int res=0;
1822         guint32 pid;
1823         int32_t counter;
1824         int32_t type;
1825         long id;
1826         int i,t;
1827         LADSPA_Plugin *plugin;
1828         char buffer[256];
1829         vtt_fx_ladspa *ladspa_effect;
1830         guint8 hidden;
1831         
1832         atload(buffer);
1833         this->set_name(buffer);
1834         atload(filename);
1835         atload(is_sync_master);
1836         atload(is_sync_client);
1837         atload(sync_cycles);
1838         atload(rel_volume);
1839         recalc_volume();
1840         atload(rel_pitch);
1841         recalc_pitch();
1842         
1843         atload(autotrigger);
1844         atload(loop);
1845         
1846         atload(mute);
1847         
1848         atload(lp_enable);
1849         atload(lp_gain);
1850         atload(lp_reso);
1851         atload(lp_freq);
1852         lp_setup(lp_gain, lp_reso, lp_freq);
1853         
1854         atload(ec_enable);
1855         atload(ec_length);
1856         ec_set_length(ec_length);
1857         atload(ec_feedback);
1858         ec_set_feedback(ec_feedback);
1859
1860         atload(pid);
1861         sp_speed.set_persistence_id(pid);
1862         atload(pid);
1863         sp_volume.set_persistence_id(pid);
1864         atload(pid);
1865         sp_pitch.set_persistence_id(pid);
1866         atload(pid);
1867         sp_trigger.set_persistence_id(pid);
1868         atload(pid);
1869         sp_loop.set_persistence_id(pid);
1870         atload(pid);
1871         sp_sync_client.set_persistence_id(pid);
1872         atload(pid);
1873         sp_sync_cycles.set_persistence_id(pid);
1874         atload(pid);
1875         sp_lp_enable.set_persistence_id(pid);
1876         atload(pid);
1877         sp_lp_gain.set_persistence_id(pid);
1878         atload(pid);
1879         sp_lp_reso.set_persistence_id(pid);
1880         atload(pid);
1881         sp_lp_freq.set_persistence_id(pid);
1882         atload(pid);
1883         sp_ec_enable.set_persistence_id(pid);
1884         atload(pid);
1885         sp_ec_length.set_persistence_id(pid);
1886         atload(pid);
1887         sp_ec_feedback.set_persistence_id(pid);
1888         atload(pid);
1889         sp_mute.set_persistence_id(pid);
1890         atload(pid);
1891         sp_spin.set_persistence_id(pid);
1892                 
1893         atload(counter);
1894         
1895         for (i=0; i<counter; i++)
1896         {
1897                 atload(type);
1898                 switch(type)
1899                 {
1900                         case TX_FX_BUILTINCUTOFF:
1901                                 for (t=0; t<fx_list.size(); t++) effect_down(lp_fx);
1902                         break;
1903                         
1904                         case TX_FX_BUILTINECHO:
1905                                 for (t=0; t<fx_list.size(); t++) effect_down(ec_fx);
1906                         break;
1907                         
1908                         case TX_FX_LADSPA:
1909                                 atload(id);
1910                                 plugin=LADSPA_Plugin::getPluginByUniqueID(id);
1911                                 if (plugin)
1912                                 {
1913                                         ladspa_effect=add_effect(plugin);
1914                                         ladspa_effect->load(input);
1915                                 }
1916                                 else
1917                                 {
1918                                         sprintf(buffer,"Fatal Error: Couldn't find required plugin with ID [%i].", id);
1919                                         tx_note(buffer);
1920                                         res++;
1921                                 }
1922                         break;
1923                         
1924                         default:
1925                                 tx_note("Fatal Error loading set: unknown effect type!");
1926                                 res++;
1927                 }               
1928         }
1929
1930         atload(pid);
1931         
1932         if (pid)
1933         {
1934                 atload(pid);
1935                 set_x_input_parameter(tX_seqpar :: get_sp_by_persistence_id(pid));
1936         }
1937         else set_x_input_parameter(NULL);
1938         
1939         atload(pid);
1940         
1941         if (pid)
1942         {
1943                 atload(pid);
1944                 set_y_input_parameter(tX_seqpar :: get_sp_by_persistence_id(pid));
1945         }
1946         else set_y_input_parameter(NULL);
1947
1948         atload(hidden);
1949         gui.main_panel->hide(hidden);
1950
1951         atload(hidden);
1952         gui.trigger_panel->hide(hidden);
1953
1954         atload(hidden);
1955         gui.lp_panel->hide(hidden);
1956
1957         atload(hidden);
1958         gui.ec_panel->hide(hidden);
1959         
1960         return(res);
1961 }
1962
1963 int vtt_class :: load_13(FILE * input)
1964 {
1965         int res=0;
1966         guint32 pid;
1967         int32_t counter;
1968         int32_t type;
1969         long id;
1970         int i,t;
1971         LADSPA_Plugin *plugin;
1972         char buffer[256];
1973         vtt_fx_ladspa *ladspa_effect;
1974         guint8 hidden;
1975         
1976         atload(buffer);
1977         this->set_name(buffer);
1978         atload(filename);
1979         atload(is_sync_master);
1980         atload(is_sync_client);
1981         atload(sync_cycles);
1982         atload(rel_volume);
1983         atload(rel_pitch);
1984         recalc_pitch();
1985         
1986         atload(autotrigger);
1987         atload(loop);
1988         
1989         atload(mute);
1990         atload(pan);
1991         
1992         atload(lp_enable);
1993         atload(lp_gain);
1994         atload(lp_reso);
1995         atload(lp_freq);
1996         lp_setup(lp_gain, lp_reso, lp_freq);
1997         
1998         atload(ec_enable);
1999         atload(ec_length);
2000         ec_set_length(ec_length);
2001         atload(ec_feedback);
2002         ec_set_feedback(ec_feedback);
2003         atload(ec_pan);
2004         ec_set_pan(ec_pan);
2005         atload(ec_volume);
2006         ec_set_volume(ec_volume);
2007
2008         recalc_volume();
2009
2010         atload(pid);
2011         sp_speed.set_persistence_id(pid);
2012         atload(pid);
2013         sp_volume.set_persistence_id(pid);
2014         atload(pid);
2015         sp_pitch.set_persistence_id(pid);
2016         atload(pid);
2017         sp_trigger.set_persistence_id(pid);
2018         atload(pid);
2019         sp_loop.set_persistence_id(pid);
2020         atload(pid);
2021         sp_sync_client.set_persistence_id(pid);
2022         atload(pid);
2023         sp_sync_cycles.set_persistence_id(pid);
2024         atload(pid);
2025         sp_lp_enable.set_persistence_id(pid);
2026         atload(pid);
2027         sp_lp_gain.set_persistence_id(pid);
2028         atload(pid);
2029         sp_lp_reso.set_persistence_id(pid);
2030         atload(pid);
2031         sp_lp_freq.set_persistence_id(pid);
2032         atload(pid);
2033         sp_ec_enable.set_persistence_id(pid);
2034         atload(pid);
2035         sp_ec_length.set_persistence_id(pid);
2036         atload(pid);
2037         sp_ec_feedback.set_persistence_id(pid);
2038         atload(pid);
2039         sp_ec_volume.set_persistence_id(pid);
2040         atload(pid);
2041         sp_ec_pan.set_persistence_id(pid);
2042         atload(pid);
2043         sp_mute.set_persistence_id(pid);
2044         atload(pid);
2045         sp_spin.set_persistence_id(pid);
2046         atload(pid);
2047         sp_pan.set_persistence_id(pid);
2048                 
2049         atload(counter);
2050         
2051         for (i=0; i<counter; i++)
2052         {
2053                 atload(type);
2054                 switch(type)
2055                 {
2056                         case TX_FX_BUILTINCUTOFF:
2057                                 for (t=0; t<fx_list.size(); t++) effect_down(lp_fx);
2058                         break;
2059                         
2060                         case TX_FX_BUILTINECHO:
2061                                 for (t=0; t<fx_list.size(); t++) effect_down(ec_fx);
2062                         break;
2063                         
2064                         case TX_FX_LADSPA:
2065                                 atload(id);
2066                                 plugin=LADSPA_Plugin::getPluginByUniqueID(id);
2067                                 if (plugin)
2068                                 {
2069                                         ladspa_effect=add_effect(plugin);
2070                                         ladspa_effect->load(input);
2071                                 }
2072                                 else
2073                                 {
2074                                         sprintf(buffer,"Fatal Error: Couldn't find required plugin with ID [%i].", id);
2075                                         tx_note(buffer);
2076                                         res++;
2077                                 }
2078                         break;
2079                         
2080                         default:
2081                                 tx_note("Fatal Error loading set: unknown effect type!");
2082                                 res++;
2083                 }               
2084         }
2085
2086         atload(pid);
2087         
2088         if (pid)
2089         {
2090                 atload(pid);
2091                 set_x_input_parameter(tX_seqpar :: get_sp_by_persistence_id(pid));
2092         }
2093         else set_x_input_parameter(NULL);
2094         
2095         atload(pid);
2096         
2097         if (pid)
2098         {
2099                 atload(pid);
2100                 set_y_input_parameter(tX_seqpar :: get_sp_by_persistence_id(pid));
2101         }
2102         else set_y_input_parameter(NULL);
2103
2104         atload(hidden);
2105         gui.main_panel->hide(hidden);
2106
2107         atload(hidden);
2108         gui.trigger_panel->hide(hidden);
2109
2110         atload(hidden);
2111         gui.lp_panel->hide(hidden);
2112
2113         atload(hidden);
2114         gui.ec_panel->hide(hidden);
2115         
2116         return(res);
2117 }
2118
2119 int vtt_class :: load_14(FILE * input)
2120 {
2121         int res=0;
2122         guint32 pid;
2123         int32_t counter;
2124         int32_t type;
2125         long id;
2126         int i,t;
2127         LADSPA_Plugin *plugin;
2128         char buffer[256];
2129         vtt_fx_ladspa *ladspa_effect;
2130         guint8 hidden;
2131         
2132         atload(buffer);
2133         this->set_name(buffer);
2134         atload(filename);
2135         atload(is_sync_master);
2136         atload(is_sync_client);
2137         atload(sync_cycles);
2138         atload(rel_volume);
2139         atload(rel_pitch);
2140         recalc_pitch();
2141         
2142         atload(autotrigger);
2143         atload(loop);
2144         
2145         atload(mute);
2146         atload(pan);
2147         
2148         atload(lp_enable);
2149         atload(lp_gain);
2150         atload(lp_reso);
2151         atload(lp_freq);
2152         lp_setup(lp_gain, lp_reso, lp_freq);
2153         
2154         atload(ec_enable);
2155         atload(ec_length);
2156         ec_set_length(ec_length);
2157         atload(ec_feedback);
2158         ec_set_feedback(ec_feedback);
2159         atload(ec_pan);
2160         ec_set_pan(ec_pan);
2161         atload(ec_volume);
2162         ec_set_volume(ec_volume);
2163
2164         atload(audio_hidden);
2165         atload(control_hidden);
2166         
2167         recalc_volume();
2168
2169         atload(pid);
2170         sp_speed.set_persistence_id(pid);
2171         atload(pid);
2172         sp_volume.set_persistence_id(pid);
2173         atload(pid);
2174         sp_pitch.set_persistence_id(pid);
2175         atload(pid);
2176         sp_trigger.set_persistence_id(pid);
2177         atload(pid);
2178         sp_loop.set_persistence_id(pid);
2179         atload(pid);
2180         sp_sync_client.set_persistence_id(pid);
2181         atload(pid);
2182         sp_sync_cycles.set_persistence_id(pid);
2183         atload(pid);
2184         sp_lp_enable.set_persistence_id(pid);
2185         atload(pid);
2186         sp_lp_gain.set_persistence_id(pid);
2187         atload(pid);
2188         sp_lp_reso.set_persistence_id(pid);
2189         atload(pid);
2190         sp_lp_freq.set_persistence_id(pid);
2191         atload(pid);
2192         sp_ec_enable.set_persistence_id(pid);
2193         atload(pid);
2194         sp_ec_length.set_persistence_id(pid);
2195         atload(pid);
2196         sp_ec_feedback.set_persistence_id(pid);
2197         atload(pid);
2198         sp_ec_volume.set_persistence_id(pid);
2199         atload(pid);
2200         sp_ec_pan.set_persistence_id(pid);
2201         atload(pid);
2202         sp_mute.set_persistence_id(pid);
2203         atload(pid);
2204         sp_spin.set_persistence_id(pid);
2205         atload(pid);
2206         sp_pan.set_persistence_id(pid);
2207                 
2208         atload(counter);
2209         
2210         for (i=0; i<counter; i++)
2211         {
2212                 atload(type);
2213                 switch(type)
2214                 {
2215                         case TX_FX_BUILTINCUTOFF:
2216                                 for (t=0; t<fx_list.size(); t++) effect_down(lp_fx);
2217                         break;
2218                         
2219                         case TX_FX_BUILTINECHO:
2220                                 for (t=0; t<fx_list.size(); t++) effect_down(ec_fx);
2221                         break;
2222                         
2223                         case TX_FX_LADSPA:
2224                                 atload(id);
2225                                 plugin=LADSPA_Plugin::getPluginByUniqueID(id);
2226                                 if (plugin)
2227                                 {
2228                                         ladspa_effect=add_effect(plugin);
2229                                         ladspa_effect->load(input);
2230                                 }
2231                                 else
2232                                 {
2233                                         sprintf(buffer,"Fatal Error: Couldn't find required plugin with ID [%i].", id);
2234                                         tx_note(buffer);
2235                                         res++;
2236                                 }
2237                         break;
2238                         
2239                         default:
2240                                 tx_note("Fatal Error loading set: unknown effect type!");
2241                                 res++;
2242                 }               
2243         }
2244
2245         atload(pid);
2246         
2247         if (pid)
2248         {
2249                 atload(pid);
2250                 set_x_input_parameter(tX_seqpar :: get_sp_by_persistence_id(pid));
2251         }
2252         else set_x_input_parameter(NULL);
2253         
2254         atload(pid);
2255         
2256         if (pid)
2257         {
2258                 atload(pid);
2259                 set_y_input_parameter(tX_seqpar :: get_sp_by_persistence_id(pid));
2260         }
2261         else set_y_input_parameter(NULL);
2262
2263         atload(hidden);
2264         gui.main_panel->hide(hidden);
2265
2266         atload(hidden);
2267         gui.trigger_panel->hide(hidden);
2268
2269         atload(hidden);
2270         gui.lp_panel->hide(hidden);
2271
2272         atload(hidden);
2273         gui.ec_panel->hide(hidden);
2274         
2275         return(res);
2276 }
2277
2278
2279 int  vtt_class :: save_all(FILE* output)
2280 {
2281         int res=0;
2282         list <vtt_class *> :: iterator vtt;
2283         guint32 pid;
2284         
2285         tX_seqpar :: create_persistence_ids();
2286         
2287         store(vtt_amount);
2288         store(master_volume);
2289         store(globals.pitch);
2290         pid=sp_master_volume.get_persistence_id();
2291         store(pid);
2292         pid=sp_master_pitch.get_persistence_id();
2293         store(pid);
2294
2295         for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
2296         {
2297                 res+=(*vtt)->save(output);
2298         }
2299         
2300         sequencer.save(output);
2301         
2302         return(res);
2303 }
2304
2305 int  vtt_class :: load_all_10(FILE* input, char *fname)
2306 {
2307         int res=0, restmp=0;
2308         list <vtt_class *> :: iterator vtt;
2309         unsigned int i, max, size;
2310         int16_t *newbuffer;
2311         vtt_class *newvtt;
2312         char ftmp[PATH_MAX];
2313         
2314         while (main_list.size())
2315         {
2316                 delete((*main_list.begin()));
2317         }
2318                 
2319         atload(max);
2320         atload(master_volume);
2321         set_master_volume(master_volume);
2322         globals.volume=master_volume;
2323         atload(globals.pitch);  
2324         set_master_pitch(globals.pitch);
2325
2326         ld_create_loaddlg(TX_LOADDLG_MODE_MULTI, max);
2327         ld_set_setname(fname);
2328
2329         for (i=0; i<max; i++)
2330         {
2331                 newvtt=new vtt_class(1);
2332                 res+=newvtt->load_10(input);
2333                 
2334                 if (strlen(newvtt->filename))
2335                 {
2336                         /* ftmp IS NECESSARY !!! */
2337                         strcpy(ftmp, newvtt->filename);
2338                         ld_set_filename(ftmp);
2339                         
2340                         //restmp=load_wav(newvtt->filename, &newbuffer, &size);
2341                         restmp=newvtt->load_file(ftmp);
2342                         res+=restmp;
2343                 }
2344                 gtk_box_pack_start(GTK_BOX(control_parent), newvtt->gui.control_box, TRUE, TRUE, 0);
2345                 gtk_box_pack_start(GTK_BOX(audio_parent), newvtt->gui.audio_box, TRUE, TRUE, 0);
2346         }
2347         
2348         sequencer.clear();
2349         
2350         ld_destroy();
2351         
2352         return(res);
2353 }
2354
2355
2356 int  vtt_class :: load_all_11(FILE* input, char *fname)
2357 {
2358         int res=0, restmp=0;
2359         list <vtt_class *> :: iterator vtt;
2360         unsigned int i, max, size;
2361         int16_t *newbuffer;
2362         vtt_class *newvtt;
2363         char ftmp[PATH_MAX];
2364         guint32 pid;
2365         
2366         while (main_list.size())
2367         {
2368                 delete((*main_list.begin()));
2369         }
2370                 
2371         atload(max);
2372         atload(master_volume);
2373         set_master_volume(master_volume);
2374         globals.volume=master_volume;
2375         atload(globals.pitch);  
2376         set_master_pitch(globals.pitch);
2377         atload(pid);
2378         sp_master_volume.set_persistence_id(pid);
2379         atload(pid);
2380         sp_master_pitch.set_persistence_id(pid);
2381
2382         ld_create_loaddlg(TX_LOADDLG_MODE_MULTI, max);
2383         ld_set_setname(fname);
2384
2385         for (i=0; i<max; i++)
2386         {
2387                 newvtt=new vtt_class(1);
2388                 res+=newvtt->load_11(input);
2389                 
2390                 if (strlen(newvtt->filename))
2391                 {
2392                         /* ftmp IS NECESSARY !!! */
2393                         strcpy(ftmp, newvtt->filename);
2394                         ld_set_filename(ftmp);
2395                         
2396                         //restmp=load_wav(newvtt->filename, &newbuffer, &size);
2397                         restmp=newvtt->load_file(ftmp);
2398                         res+=restmp;
2399                 }
2400                 gtk_box_pack_start(GTK_BOX(control_parent), newvtt->gui.control_box, TRUE, TRUE, 0);
2401                 gtk_box_pack_start(GTK_BOX(audio_parent), newvtt->gui.audio_box, TRUE, TRUE, 0);
2402                 
2403         }
2404         
2405         sequencer.load(input);
2406         
2407         ld_destroy();
2408         
2409         return(res);
2410 }
2411
2412
2413 int  vtt_class :: load_all_12(FILE* input, char *fname)
2414 {
2415         int res=0, restmp=0;
2416         list <vtt_class *> :: iterator vtt;
2417         unsigned int i, max, size;
2418         int16_t *newbuffer;
2419         vtt_class *newvtt;
2420         char ftmp[PATH_MAX];
2421         guint32 pid;
2422         
2423         while (main_list.size())
2424         {
2425                 delete((*main_list.begin()));
2426         }
2427                 
2428         atload(max);
2429         atload(master_volume);
2430         set_master_volume(master_volume);
2431         globals.volume=master_volume;
2432         atload(globals.pitch);  
2433         set_master_pitch(globals.pitch);
2434         atload(pid);
2435         sp_master_volume.set_persistence_id(pid);
2436         atload(pid);
2437         sp_master_pitch.set_persistence_id(pid);
2438
2439         ld_create_loaddlg(TX_LOADDLG_MODE_MULTI, max);
2440         ld_set_setname(fname);
2441
2442         for (i=0; i<max; i++)
2443         {
2444                 newvtt=new vtt_class(1);
2445                 res+=newvtt->load_12(input);
2446                 
2447                 if (strlen(newvtt->filename))
2448                 {
2449                         /* ftmp IS NECESSARY !!! */
2450                         strcpy(ftmp, newvtt->filename);
2451                         ld_set_filename(ftmp);
2452                         
2453                         //restmp=load_wav(newvtt->filename, &newbuffer, &size);
2454                         restmp=newvtt->load_file(ftmp);
2455                         res+=restmp;
2456                 }
2457                 gtk_box_pack_start(GTK_BOX(control_parent), newvtt->gui.control_box, TRUE, TRUE, 0);
2458                 gtk_box_pack_start(GTK_BOX(audio_parent), newvtt->gui.audio_box, TRUE, TRUE, 0);
2459                 
2460         }
2461         
2462         sequencer.load(input);
2463         
2464         ld_destroy();
2465         
2466         return(res);
2467 }
2468
2469 int  vtt_class :: load_all_13(FILE* input, char *fname)
2470 {
2471         int res=0, restmp=0;
2472         list <vtt_class *> :: iterator vtt;
2473         unsigned int i, max, size;
2474         int16_t *newbuffer;
2475         vtt_class *newvtt;
2476         char ftmp[PATH_MAX];
2477         guint32 pid;
2478         
2479         while (main_list.size())
2480         {
2481                 delete((*main_list.begin()));
2482         }
2483                 
2484         atload(max);
2485         atload(master_volume);
2486         set_master_volume(master_volume);
2487         globals.volume=master_volume;
2488         atload(globals.pitch);  
2489         set_master_pitch(globals.pitch);
2490         atload(pid);
2491         sp_master_volume.set_persistence_id(pid);
2492         atload(pid);
2493         sp_master_pitch.set_persistence_id(pid);
2494
2495         ld_create_loaddlg(TX_LOADDLG_MODE_MULTI, max);
2496         ld_set_setname(fname);
2497
2498         for (i=0; i<max; i++)
2499         {
2500                 newvtt=new vtt_class(1);
2501                 res+=newvtt->load_13(input);
2502                 
2503                 if (strlen(newvtt->filename))
2504                 {
2505                         /* ftmp IS NECESSARY !!! */
2506                         strcpy(ftmp, newvtt->filename);
2507                         ld_set_filename(ftmp);
2508                         
2509                         //restmp=load_wav(newvtt->filename, &newbuffer, &size);
2510                         restmp=newvtt->load_file(ftmp);
2511                         res+=restmp;
2512                 }
2513                 gtk_box_pack_start(GTK_BOX(control_parent), newvtt->gui.control_box, TRUE, TRUE, 0);
2514                 gtk_box_pack_start(GTK_BOX(audio_parent), newvtt->gui.audio_box, TRUE, TRUE, 0);
2515                 
2516         }
2517         
2518         sequencer.load(input);
2519         
2520         ld_destroy();
2521         
2522         return(res);
2523 }
2524
2525 int  vtt_class :: load_all_14(FILE* input, char *fname)
2526 {
2527         int res=0, restmp=0;
2528         list <vtt_class *> :: iterator vtt;
2529         unsigned int i, max, size;
2530         int16_t *newbuffer;
2531         vtt_class *newvtt;
2532         char ftmp[PATH_MAX];
2533         guint32 pid;
2534         
2535         while (main_list.size())
2536         {
2537                 delete((*main_list.begin()));
2538         }
2539                 
2540         atload(max);
2541         atload(master_volume);
2542         set_master_volume(master_volume);
2543         globals.volume=master_volume;
2544         atload(globals.pitch);  
2545         set_master_pitch(globals.pitch);
2546         atload(pid);
2547         sp_master_volume.set_persistence_id(pid);
2548         atload(pid);
2549         sp_master_pitch.set_persistence_id(pid);
2550
2551         ld_create_loaddlg(TX_LOADDLG_MODE_MULTI, max);
2552         ld_set_setname(fname);
2553
2554         for (i=0; i<max; i++)
2555         {
2556                 newvtt=new vtt_class(1);
2557                 res+=newvtt->load_14(input);
2558                 
2559                 if (strlen(newvtt->filename))
2560                 {
2561                         /* ftmp IS NECESSARY !!! */
2562                         strcpy(ftmp, newvtt->filename);
2563                         ld_set_filename(ftmp);
2564                         
2565                         //restmp=load_wav(newvtt->filename, &newbuffer, &size);
2566                         restmp=newvtt->load_file(ftmp);
2567                         res+=restmp;
2568                 }
2569                 gtk_box_pack_start(GTK_BOX(control_parent), newvtt->gui.control_box, TRUE, TRUE, 0);
2570                 gtk_box_pack_start(GTK_BOX(audio_parent), newvtt->gui.audio_box, TRUE, TRUE, 0);
2571             if (newvtt->audio_hidden) newvtt->hide_audio(newvtt->audio_hidden);
2572             if (newvtt->control_hidden) newvtt->hide_control(newvtt->control_hidden);\r
2573         }
2574         
2575         sequencer.load(input);
2576         
2577         ld_destroy();
2578         
2579         return(res);
2580 }
2581
2582
2583 void add_vtt(GtkWidget *ctrl, GtkWidget *audio, char *fn)
2584 {
2585         vtt_class *hmmpg;
2586         hmmpg = new vtt_class(1);
2587         gtk_box_pack_start(GTK_BOX(ctrl), hmmpg->gui.control_box, TRUE, TRUE, 0);
2588         gtk_box_pack_start(GTK_BOX(audio), hmmpg->gui.audio_box, TRUE, TRUE, 0);
2589         if (fn) hmmpg->load_file(fn);
2590 }
2591
2592 extern void vg_move_fx_panel_up(GtkWidget *wid, vtt_class *vtt);
2593 extern void vg_move_fx_panel_down(GtkWidget *wid, vtt_class *vtt);
2594
2595 //#define debug_fx_stack(); for (i=fx_list.begin(); i != fx_list.end(); i++) puts((*i)->get_info_string());
2596 #define debug_fx_stack();
2597
2598 void vtt_class :: effect_up(vtt_fx *effect)
2599 {
2600         list <vtt_fx *> :: iterator i;
2601         list <vtt_fx *> :: iterator previous;
2602         int ok=0;
2603         
2604         debug_fx_stack();
2605         
2606         if ((*fx_list.begin())==effect) return;
2607         
2608         for (previous=i=fx_list.begin(); i != fx_list.end(); i++)
2609         {
2610                 if ((*i) == effect)
2611                 {
2612                         ok=1;
2613                         break;
2614                 }
2615                 previous=i;
2616         }
2617         
2618         if (ok)
2619         {       
2620                 pthread_mutex_lock(&render_lock);
2621                 fx_list.remove(effect);
2622                 fx_list.insert(previous, effect);
2623                 pthread_mutex_unlock(&render_lock);
2624
2625                 vg_move_fx_panel_up(effect->get_panel_widget(), this);
2626         }
2627         
2628         debug_fx_stack();
2629 }
2630
2631 void vtt_class :: effect_down(vtt_fx *effect)
2632 {
2633         list <vtt_fx *> :: iterator i;
2634         int ok=0;
2635
2636         debug_fx_stack();
2637                 
2638         for (i=fx_list.begin(); i != fx_list.end(); i++)
2639         {
2640                 if ((*i) == effect)
2641                 {
2642                         ok=1;
2643                         break;
2644                 }
2645         }
2646         
2647         if ((ok) && (i!=fx_list.end()))
2648         {
2649                 i++;
2650                 if (i==fx_list.end()) return;
2651                 i++;
2652
2653                 pthread_mutex_lock(&render_lock);
2654                 fx_list.remove(effect);
2655                 
2656                 fx_list.insert(i, effect);
2657                 vg_move_fx_panel_down(effect->get_panel_widget(), this);
2658                 pthread_mutex_unlock(&render_lock);
2659         }
2660         
2661 debug_fx_stack();       
2662 }
2663
2664 void vtt_class ::  effect_remove(vtt_fx_ladspa *effect)
2665 {
2666         pthread_mutex_lock(&render_lock);
2667         fx_list.remove(effect);
2668         pthread_mutex_unlock(&render_lock);
2669         
2670         delete effect;
2671 }
2672
2673 extern void gui_hide_control_panel(vtt_class *vtt, bool hide);
2674 extern void gui_hide_audio_panel(vtt_class *vtt, bool hide);
2675
2676 void vtt_class :: hide_audio(bool hide) {
2677         audio_hidden=hide;
2678         gui_hide_audio_panel(this, hide);
2679 }
2680
2681 void vtt_class :: hide_control(bool hide) {
2682         control_hidden=hide;
2683         gui_hide_control_panel(this, hide);     
2684 }