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