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