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