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