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