MIDI set_sync_client fix, cleanups, compilation fixes for gcc 2.95 - Alex
[terminatorX.git] / src / tX_vtt.cc
1 /*
2     terminatorX - realtime audio scratching software
3     Copyright (C) 1999-2003  Alexander K├Ânig
4  
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9  
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14  
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  
19     File: tX_vtt.cc
20  
21     Description: This implements the new virtual turntable class. It replaces
22                  the old turntable.c from terminatorX 3.2 and earlier. The lowpass
23                  filter is based on some sample code by Paul Kellett
24                  <paul.kellett@maxim.abel.co.uk>
25                  
26     08 Dec 1999 - Switched to the new audiofile class            
27 */    
28
29 #include "tX_vtt.h"
30 #include "tX_global.h"
31 #include <stdio.h>
32 #include "malloc.h"
33 #include <math.h>
34 #include "tX_mastergui.h"
35 #include "tX_sequencer.h"
36 #include <glib.h>
37
38 #ifdef HAVE_CONFIG_H
39 #include <config.h>
40 #endif
41
42 #ifdef DEBUG
43 #define tX_freemem(ptr, varname, comment); fprintf(stderr, "** free() [%s] at %08x. %s.\n", varname, ptr, comment); free(ptr);
44 #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);
45 #else
46 #define tX_freemem(ptr, varname, comment); free(ptr);
47 #define tX_malloc(ptr, varname, comment, size, type); ptr=type malloc(size);
48 #endif
49
50 #include "tX_loaddlg.h"
51
52 #define USE_PREFETCH 1
53
54 #ifdef USE_PREFETCH
55 #define my_prefetch(base, index); __asm__  __volatile__ ("prefetch index(%0)\n" : : "r" (base));
56 #define my_prefetchw(base, index); __asm__  __volatile__ ("prefetchw index(%0)\n" : : "r" (base));
57 #else
58 #define my_prefetch(base, index);  /* NOP */;
59 #define my_prefetchw(base, index); /* NOP */;
60 #endif
61
62 extern void build_vtt_gui(vtt_class *);
63 extern void gui_set_name(vtt_class *vtt, char *newname);
64 extern void gui_set_filename(vtt_class *vtt, char *newname);
65 extern void delete_gui(vtt_class *vtt);
66 extern void gui_update_display(vtt_class *vtt);
67 extern void gui_clear_master_button(vtt_class *vtt);
68 extern void cleanup_vtt(vtt_class *vtt);
69 extern int vg_get_current_page(vtt_class *vtt);
70 extern f_prec gui_get_audio_x_zoom(vtt_class *vtt);
71 extern void gui_set_audio_x_zoom(vtt_class *vtt, f_prec);
72
73 int vtt_class::last_sample_rate=44100;
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
87 vtt_class * vtt_class::sync_master=NULL;
88 int vtt_class::master_triggered=0;
89 int vtt_class::master_triggered_at=0;
90 vtt_class * vtt_class::focused_vtt=NULL;
91 f_prec vtt_class::mix_max_l=0;
92 f_prec vtt_class::mix_max_r=0;
93 f_prec vtt_class::vol_channel_adjust=1.0;
94 int vtt_class::mix_buffer_size=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         pos_i_max=0;
106
107         pan=0;
108         rel_pitch=1; 
109         ec_volume=1; 
110         ec_pan=1; 
111         audiofile_pitch_correction=1.0;
112         ec_length=1;
113         ec_output_buffer=NULL;
114         output_buffer=NULL;
115         
116         set_volume(1);
117         set_pitch(1);
118         
119         autotrigger=1;
120         loop=1;
121         
122         is_playing=0;
123         is_sync_master=0;
124         is_sync_client=0;
125         sync_cycles=0,
126         sync_countdown=0;
127         
128         lp_enable=0;
129         lp_reso=0.8;
130         lp_freq=0.3;
131         lp_gain=1;
132         lp_setup(lp_gain, lp_reso, lp_freq);
133         lp_reset();
134         
135         ec_enable=0;
136         ec_length=0.5;
137         ec_feedback=0.3;
138         ec_clear_buffer();
139         ec_set_length(0.5);
140         ec_set_pan(0);
141         ec_set_volume(1);
142         
143         main_list.push_back(this);
144
145         /* "connecting" the seq-parameters */
146         
147         sp_speed.set_vtt((void *) this);
148         sp_volume.set_vtt((void *) this);       
149         sp_pitch.set_vtt((void *) this);        
150         sp_pan.set_vtt((void *) this);
151         sp_trigger.set_vtt((void *) this);      
152         sp_loop.set_vtt((void *) this); 
153         sp_sync_client.set_vtt((void *) this);  
154         sp_sync_cycles.set_vtt((void *) this);  
155         sp_lp_enable.set_vtt((void *) this);    
156         sp_lp_gain.set_vtt((void *) this);      
157         sp_lp_reso.set_vtt((void *) this);      
158         sp_lp_freq.set_vtt((void *) this);      
159         sp_ec_enable.set_vtt((void *) this);    
160         sp_ec_length.set_vtt((void *) this);
161         sp_ec_pan.set_vtt((void *) this);
162         sp_ec_volume.set_vtt((void *) this);
163         sp_ec_feedback.set_vtt((void *) this);          
164         sp_mute.set_vtt((void *) this);
165         sp_spin.set_vtt((void *) this);
166
167         x_par = &sp_speed;
168         y_par = &sp_lp_freq;
169         
170         lp_fx=new vtt_fx_lp();
171         lp_fx->set_vtt((void *) this);
172         fx_list.push_back(lp_fx);
173
174         ec_fx=new vtt_fx_ec();
175         ec_fx->set_vtt((void *) this);
176         fx_list.push_back(ec_fx);
177         
178         if (do_create_gui)
179         {       
180                 build_vtt_gui(this);
181                 lp_fx->set_panel_widget(gui.lp_panel->get_widget());    
182                 ec_fx->set_panel_widget(gui.ec_panel->get_widget());
183         }
184         else have_gui=0;
185                 
186         set_pan(0);     
187         set_master_volume(globals.volume);
188         set_output_buffer_size(samples_in_mix_buffer/2);
189         
190         audiofile = NULL;
191         audiofile_pitch_correction=1.0;
192         mute=0;
193         mix_solo=0;
194         mix_mute=0;
195         res_mute=mute;
196         res_mute_old=0;
197         
198         audio_hidden=false;
199         control_hidden=false;
200         
201         do_scratch=0;
202         speed_last=1;
203         speed_real=1;\r
204 }
205
206 vtt_class :: ~vtt_class()
207 {
208         vtt_fx *effect;
209         stop();
210
211         main_list.remove(this);
212         if (audiofile) delete audiofile;
213         //if (buffer) free(buffer);
214         if (output_buffer) tX_freemem(output_buffer, "output_buffer", "vtt Destructor");
215         vtt_amount--;
216         
217         if (mix_solo) solo_ctr--;
218         
219         while (fx_list.size())
220         { 
221                 effect=(*fx_list.begin());
222                 fx_list.remove(effect);
223                 delete effect;
224         }
225         
226         if (sync_master==this) {
227                 sync_master=NULL;
228         }
229         
230         delete_gui(this);
231 }
232
233 void vtt_class :: set_name(char *newname)
234 {
235         strcpy(name, newname);
236         gui_set_name(this, name);       
237 }
238
239 tX_audio_error vtt_class :: load_file(char *fname)
240 {
241         tX_audio_error res;
242         int was_playing=is_playing;
243         
244         if (is_playing) stop();
245
246         if (audiofile) delete(audiofile);
247         
248         buffer=NULL;
249         samples_in_buffer=0;
250         maxpos=0;
251         pos_i_max=0;
252         strcpy(filename,"");
253
254         audiofile=new tx_audiofile();
255         res=audiofile->load(fname);     
256         
257         if (res==TX_AUDIO_SUCCESS) {
258                 buffer=audiofile->get_buffer();
259                 double file_rate=audiofile->get_sample_rate();
260                 audiofile_pitch_correction=file_rate/((double) last_sample_rate);
261                 recalc_pitch();
262                 samples_in_buffer=audiofile->get_no_samples();
263                 pos_i_max=samples_in_buffer-1;
264                 maxpos=audiofile->get_no_samples();
265                 strcpy(filename, fname);
266                 if (was_playing) trigger();
267 //              printf("Successfully loaded %s, %08x, %i\n", fname, buffer, samples_in_buffer);
268         }
269         
270         if (have_gui)
271         {
272                 gui_update_display(this);
273         }
274         ec_set_length(ec_length);
275         
276         return(res);
277 }
278
279 int vtt_class :: set_output_buffer_size(int newsize)
280 {
281         list <vtt_fx *> :: iterator effect;
282
283         if (ec_output_buffer) tX_freemem(ec_output_buffer, "ec_output_buffer", "vtt set_output_buffer_size()");
284         tX_malloc(ec_output_buffer, "ec_output_buffer", "vtt set_output_buffer_size()", sizeof(float)*newsize, (float *));
285
286         if (output_buffer) tX_freemem(output_buffer, "output_buffer", "vtt set_output_buffer_size()");
287         tX_malloc(output_buffer, "output_buffer", "vtt set_output_buffer_size()", sizeof(float)*newsize, (float *));
288
289         end_of_outputbuffer = output_buffer + newsize; //size_t(sizeof(float)*(newsize));
290         
291         samples_in_outputbuffer=newsize;
292         inv_samples_in_outputbuffer=1.0/samples_in_outputbuffer;
293
294         for (effect=fx_list.begin(); effect != fx_list.end(); effect++)
295         {
296                 (*effect)->reconnect_buffer();
297         }
298         
299         if (output_buffer) return(0);   
300         else return(0);
301 }
302
303 void vtt_class :: set_volume(f_prec newvol)
304 {
305         rel_volume=newvol;
306         recalc_volume();
307 }
308
309 void vtt_class :: recalc_volume()
310 {
311         res_volume=rel_volume*res_master_volume;
312         f_prec ec_res_volume=res_volume*ec_volume;
313         
314         if (pan>0.0)
315         {
316                 res_volume_left=(1.0-pan)*res_volume;
317                 res_volume_right=res_volume;
318         }
319         else if (pan<0.0)
320         {
321                 res_volume_left=res_volume;
322                 res_volume_right=(1.0+pan)*res_volume;
323         }
324         else
325         {
326                 res_volume_left=res_volume_right=res_volume;
327         }
328         
329         if (ec_pan>0.0)
330         {
331                 ec_volume_left=(1.0-ec_pan)*ec_res_volume;
332                 ec_volume_right=ec_res_volume;
333         }
334         else if (ec_pan<0.0)
335         {
336                 ec_volume_left=ec_res_volume;
337                 ec_volume_right=(1.0+ec_pan)*ec_res_volume;
338         }
339         else
340         {
341                 ec_volume_left=ec_volume_right=ec_res_volume;
342         }       
343 //      printf("vtt_volume: %f, %f, l: %f, r: %f\n", rel_volume, res_volume, res_volume_left, res_volume_right);
344 }
345
346 void vtt_class :: set_pan(f_prec newpan)
347 {
348         pan=newpan;
349         recalc_volume();
350 }
351
352 void vtt_class :: set_pitch(f_prec newpitch)
353 {
354         rel_pitch=newpitch;
355         recalc_pitch();
356 }
357
358 void vtt_class :: recalc_pitch()
359 {
360         res_pitch=globals.pitch*rel_pitch;
361         res_pitch*=audiofile_pitch_correction;
362         speed=res_pitch;
363         ec_set_length(ec_length);
364 }
365
366 void vtt_class :: set_autotrigger(int newstate)
367 {
368         autotrigger=newstate;
369 }
370
371 void vtt_class :: set_loop(int newstate)
372 {
373         loop=newstate;
374 }
375
376 void vtt_class :: set_mute(int newstate)
377 {
378         mute=newstate;
379         calc_mute();
380 }
381
382 void vtt_class :: set_mix_mute(int newstate)
383 {
384         mix_mute=newstate;
385         calc_mute();
386 }
387
388 void vtt_class :: set_mix_solo(int newstate)
389 {
390         if (mix_solo && !newstate)
391         {
392                 /* turning it off */
393                 mix_solo=0;
394                 solo_ctr--;
395         }
396         else if (!mix_solo && newstate)
397         {
398                 /* turning it on */
399                 mix_solo=1;
400                 solo_ctr++;
401         }
402         calc_mute();
403
404         /* locking ? */
405         list <vtt_class *> :: iterator vtt;
406         
407         for (vtt=main_list.begin(); vtt!=main_list.end() ; vtt++)
408         {
409                 (*vtt)->calc_mute();
410         }
411 }
412
413 void vtt_class :: lp_set_enable (int newstate)
414 {
415         lp_enable=newstate;
416         lp_reset();
417 }
418
419 void vtt_class :: lp_reset()
420 {
421         lp_buf0=lp_buf1=0;
422 }
423
424 void vtt_class :: lp_set_gain (f_prec gain)
425 {
426         lp_gain=gain;
427         lp_resgain=lp_gain*lp_autogain;
428 }
429
430 void vtt_class :: lp_set_reso(f_prec reso)
431 {
432         lp_reso=reso;
433         
434         lp_b=reso*(1.0+(1.0/lp_a));
435         lp_autogain=1.0-reso*GAIN_AUTO_ADJUST;
436         lp_resgain=lp_gain*lp_autogain;
437 }
438
439 void vtt_class :: lp_set_freq(f_prec freq)
440 {
441         lp_freq=freq;
442         
443         lp_a=0.9999-freq;
444         lp_b=lp_reso*(1.0+(1.0/lp_a));
445 }
446
447 void vtt_class :: lp_setup(f_prec gain, f_prec reso, f_prec freq)
448 {
449         lp_freq=freq;
450         lp_reso=reso;
451         
452         lp_a=1.0-freq;
453         lp_b=reso*(1.0+(1.0/lp_a));
454         
455         lp_autogain=1.0-reso*GAIN_AUTO_ADJUST;
456         lp_resgain=lp_gain*lp_autogain;
457 }
458
459 void vtt_class :: ec_set_enable(int newstate)
460 {
461         ec_enable=newstate;
462         ec_clear_buffer();
463 }
464
465
466 void vtt_class :: ec_set_pan(f_prec pan)
467 {
468         ec_pan=pan;
469
470         recalc_volume();
471 }
472
473 /* Max length is 1.0 */
474
475 void vtt_class :: ec_set_length(f_prec length)
476 {
477         int delay;
478
479         ec_length=length;
480         if (res_pitch==0) 
481         {
482                 ec_res_length=length*samples_in_buffer;
483         }
484         else
485         {
486                 ec_res_length=length*samples_in_buffer/res_pitch;       
487         }
488         
489         if (ec_res_length<0) ec_res_length*=-1;
490         
491         if (ec_res_length>=EC_MAX_BUFFER)
492         {
493                 ec_res_length=EC_MAX_BUFFER*length;
494         }
495         
496         delay=(int )floor(ec_res_length);
497         delay-=2;
498         ec_delay=&ec_buffer[delay];
499 }
500
501 void vtt_class :: ec_set_feedback(f_prec feedback)
502 {
503         ec_feedback=feedback;
504 }
505
506
507 void vtt_class :: ec_set_volume(f_prec volume)
508 {
509         ec_volume=volume;
510         recalc_volume();
511 }
512
513 void vtt_class :: ec_clear_buffer()
514 {
515         f_prec *ptr;
516         
517         for (ptr=ec_buffer; ptr<=ec_delay; ptr++) {
518                 *ptr=0.0;
519         }
520         ec_ptr=ec_buffer;
521 }
522
523 void vtt_class :: render()
524 {
525         list <vtt_fx *> :: iterator effect;
526
527         if (do_scratch) {
528                 if (sense_cycles>0) {
529                         sense_cycles--;
530                         if (sense_cycles==0) sp_speed.receive_input_value(0);
531                 }
532         }
533         render_scratch();
534         
535         for (effect=fx_list.begin(); effect != fx_list.end(); effect++) {
536                 if ((*effect)->isEnabled()) (*effect)->run();
537         }
538 }
539
540 extern void vg_create_fx_gui(vtt_class *vtt, vtt_fx_ladspa *effect, LADSPA_Plugin *plugin);
541
542 vtt_fx_ladspa * vtt_class :: add_effect (LADSPA_Plugin *plugin)
543 {
544         vtt_fx_ladspa *new_effect;
545         
546         new_effect = new vtt_fx_ladspa (plugin, this);
547         pthread_mutex_lock(&render_lock);
548         fx_list.push_back(new_effect);
549         if (is_playing) new_effect->activate();
550         pthread_mutex_unlock(&render_lock);
551         vg_create_fx_gui(this, new_effect, plugin);
552         
553         return new_effect;
554 }
555
556 void vtt_class :: calc_speed()
557 {
558         do_mute=0;
559         fade_out=0;
560         fade_in=0;
561
562         if (speed != speed_target) {
563                 speed_target=speed;
564                 speed_step=speed_target-speed_real;
565                 speed_step/=globals.vtt_inertia;
566         }
567                         
568         if (speed_target != speed_real) {
569                 speed_real+=speed_step;
570                 if ((speed_step<0) && (speed_real<speed_target)) speed_real=speed_target;
571                 else if ((speed_step>0) && (speed_real>speed_target)) speed_real=speed_target;                  
572         }
573         
574         if (fade) {
575                 if ((speed_last==0) && (speed_real !=0)) {
576                         fade_in=1;
577                         fade=NEED_FADE_OUT;
578                 }
579         } else {
580                 if ((speed_last!=0) && (speed_real==0)) {
581                         fade_out=1;
582                         fade=NEED_FADE_IN;
583                 }
584         }
585
586         speed_last = speed_real;
587
588         if (res_mute != res_mute_old) {
589                 if (res_mute) {
590                         fade_out=1; fade_in=0;
591                         fade=NEED_FADE_IN;
592                 } else {
593                         fade_in=1; fade_out=0;
594                         fade=NEED_FADE_OUT;
595                 }
596                 res_mute_old=res_mute;
597         } else {
598                 if (res_mute) do_mute=1;
599         }       
600 }
601
602 void vtt_class :: render_scratch()
603 {
604         int16_t *ptr;
605         
606         int sample;
607         
608         d_prec pos_a_f;
609         
610         f_prec amount_a;
611         f_prec amount_b;
612
613         f_prec sample_a;
614         f_prec sample_b;
615         
616         f_prec sample_res;
617         
618         f_prec *out;
619         f_prec fade_vol;        
620
621         calc_speed();
622                                         
623         for (sample =0,out=output_buffer, fade_vol=0.0; sample < samples_in_outputbuffer;sample++, out++, fade_vol+=inv_samples_in_outputbuffer) {
624                 if ((speed_real!=0) || (fade_out)) {
625
626                         pos_f+=speed_real;
627
628                         if (pos_f>maxpos) {
629                                 pos_f-=maxpos;
630                                 if (res_pitch>0) {
631                                         if (loop) {
632                                                 if (is_sync_master)
633                                                 {
634                                                         master_triggered=1;
635                                                         master_triggered_at=sample;
636                                                 }
637                                         } else {
638                                                 want_stop=1;
639                                         }
640                                 }
641                         } else if (pos_f<0) {
642                                 pos_f+=maxpos;
643                                 if (res_pitch<0) {
644                                         if (loop) {
645                                                 if (is_sync_master)
646                                                 {
647                                                         master_triggered=1;
648                                                         master_triggered_at=sample;
649                                                 }
650                                         } else {
651                                                 want_stop=1;
652                                         }
653                                 }
654                         }
655                                 
656                         pos_a_f=floor(pos_f);
657                         pos_i=(unsigned int) pos_a_f;
658                                                                 
659                         amount_b=pos_f-pos_a_f;                         
660                         amount_a=1.0-amount_b;                          
661                                 
662                         if (do_mute) {
663                                 *out=0.0;
664                         } else {
665                                 ptr=&buffer[pos_i];
666                                 sample_a=(f_prec) *ptr;
667                         
668                                 if (pos_i == pos_i_max)  {
669                                         sample_b=*buffer;
670                                 } else {
671                                         ptr++;
672                                         sample_b=(f_prec) *ptr;
673                                 }
674                                 
675                                 sample_res=(sample_a*amount_a)+(sample_b*amount_b);
676                                                                 
677                                 if (fade_in) {
678                                         sample_res*=fade_vol;
679                                 } else if (fade_out) {
680                                         sample_res*=1.0-fade_vol;
681                                 }
682  
683                                 *out=sample_res;
684                         }
685                 } else {
686                                 *out=0;
687                 }
688         }
689 }       
690
691 void vtt_class :: forward_turntable()
692 {
693         int sample;
694         double pos_f_tmp;
695 #ifdef pos_f_test
696         int show=0;
697         double diff;
698 #endif
699
700         calc_speed();
701
702         if ((speed_real==0) && (!fade_out)) return;
703         
704         
705         /* following code is problematic as adding speed_real*n is
706           different from adding speed_real n times to pos_f.
707           
708           well it speeds things up quite a bit and double precision
709           seems to do a satisfying job.
710           
711           #define pos_f_test to prove that.
712         */
713         
714         pos_f_tmp=pos_f+speed_real*samples_in_outputbuffer;
715         
716         if ((pos_f_tmp > 0) && (pos_f_tmp < maxpos)) {
717 #ifdef pos_f_test
718                 show=1;
719 #else   
720                 pos_f=pos_f_tmp;
721                 return;
722 #endif          
723         }
724                                 
725         /* now the slow way ;) */
726         
727         for (sample =0; sample < samples_in_outputbuffer; sample++) {
728                 pos_f+=speed_real;
729
730                 if (pos_f>maxpos) {
731                         pos_f-=maxpos;
732                         if (res_pitch>0) {
733                                 if (loop) {
734                                         if (is_sync_master) {
735                                                 master_triggered=1;
736                                                 master_triggered_at=sample;
737                                         }
738                                 } else {
739                                         want_stop=1;
740                                 }
741                         }
742                 } else if (pos_f<0) {
743                         pos_f+=maxpos;
744                         if (res_pitch<0) {
745                                 if (loop) {
746                                         if (is_sync_master) {
747                                                 master_triggered=1;
748                                                 master_triggered_at=sample;
749                                         }
750                                 } else {
751                                         want_stop=1;
752                                 }
753                         }
754                 }
755         }
756 #ifdef pos_f_test
757         if (show) {
758                 diff=pos_f_tmp-pos_f;
759                 if (diff!=0) printf("fast: %f, slow: %f, diff: %f, tt: %s\n", pos_f_tmp, pos_f, diff, name);
760         }
761 #endif  
762 }       
763
764 /*
765         The following lowpass filter is based on some sample code by
766         Paul Kellett <paul.kellett@maxim.abel.co.uk>
767 */
768
769 void vtt_class :: render_lp()
770 {
771         f_prec *sample;
772                 
773         for (sample = output_buffer; sample<end_of_outputbuffer; sample++) {
774                 lp_buf0 = lp_a * lp_buf0 + lp_freq * ((*sample)*lp_resgain + lp_b * (lp_buf0 - lp_buf1));
775                 lp_buf1 = lp_a * lp_buf1 + lp_freq * lp_buf0;
776                 
777                 *sample=lp_buf1;
778         }
779 }
780
781 void vtt_class :: render_ec()
782 {
783         f_prec *sample;
784         f_prec *ec_sample;
785         int i;
786
787         for (i=0, sample = output_buffer, ec_sample=ec_output_buffer; i<samples_in_outputbuffer; i++, ec_sample++,sample++, ec_ptr++) {
788                 if (ec_ptr>ec_delay) ec_ptr=ec_buffer;
789                 *ec_sample=(*ec_ptr) *ec_feedback;
790                 *ec_ptr=*sample+*ec_sample;
791         }       
792 }
793
794 int vtt_class :: set_mix_buffer_size(int no_samples)
795 {
796         list <vtt_class *> :: iterator vtt;
797         int res=0;
798         
799 //      printf("vtt_class::set_mix_buffer_size(), mix_buffer: %12x, mix_out: %12x, samples: %i\n", mix_buffer, mix_out_buffer, no_samples);
800         
801         if (mix_buffer) tX_freemem(mix_buffer, "mix_buffer", "vtt set_mix_buffer_size()");
802         samples_in_mix_buffer=no_samples*2;
803
804         tX_malloc(mix_buffer, "mix_buffer", "vtt set_mix_buffer_size()", sizeof(float)*samples_in_mix_buffer, (float *));
805         mix_buffer_end=mix_buffer+samples_in_mix_buffer;
806
807 //      printf("mix_buffer: %12x\n", mix_buffer);
808 //      printf("mix_samples: %i, out_samples: %i", samples_in_mix_buffer, no_samples);
809         
810         if (mix_out_buffer) tX_freemem(mix_out_buffer, "mix_out_buffer", "vtt set_mix_buffer_size()");
811         tX_malloc(mix_out_buffer, "mix_out_buffer", "vtt set_mix_buffer_size()", sizeof(int16_t)*samples_in_mix_buffer + 4, (int16_t *));
812
813 //      printf("mix_out_buffer: %12x\n", mix_out_buffer);
814         
815         for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++) {
816                 res|=(*vtt)->set_output_buffer_size(no_samples);
817         }
818         
819         if ((!mix_buffer) || (!mix_out_buffer) || res) return(1);
820         
821         mix_buffer_size=no_samples;
822         
823         return(0);
824 }
825
826 int16_t * vtt_class :: render_all_turntables()
827 {
828         list <vtt_class *> :: iterator vtt, next;
829         int sample;
830         int mix_sample;
831         f_prec temp;
832         f_prec max;
833         f_prec min;
834         
835         pthread_mutex_lock(&render_lock);
836         
837         if (render_list.size()==0) {
838                 memset((void *) mix_out_buffer, 0, sizeof(int16_t)*samples_in_mix_buffer);
839                 /* We need to memset mix_buffer, too, as the JACK backend
840                    acesses this directly.
841                 */
842                 memset((void *) mix_buffer, 0, sizeof(float)*samples_in_mix_buffer);
843         } else {
844                         vtt=render_list.begin();
845                         (*vtt)->render();                       
846                         max=(*vtt)->max_value;
847                         min=max;
848
849                         for (sample=0, mix_sample=0; sample<(*vtt)->samples_in_outputbuffer; sample++) {                                
850                                 temp=(*vtt)->output_buffer[sample];
851                                 mix_buffer[mix_sample]=temp*(*vtt)->res_volume_left;
852                                 mix_sample++;
853                                 mix_buffer[mix_sample]=temp*(*vtt)->res_volume_right;
854                                 mix_sample++;
855                                 
856                                 if (temp>max) max=temp;
857                                 else if (temp<min) min=temp;
858                         }
859                         
860                         min*=-1.0;
861                         if (min>max) (*vtt)->max_value=min; else (*vtt)->max_value=max;
862
863                         if ((*vtt)->ec_enable) {
864                                 for (sample=0, mix_sample=0; sample<(*vtt)->samples_in_outputbuffer; sample++) {                                
865                                         temp=(*vtt)->ec_output_buffer[sample];
866                                         
867                                         mix_buffer[mix_sample]+=temp*(*vtt)->ec_volume_left;
868                                         mix_sample++;
869                                         mix_buffer[mix_sample]+=temp*(*vtt)->ec_volume_right;
870                                         mix_sample++;
871                                 }
872                         }
873                         
874                         if (master_triggered) {
875                                 pthread_mutex_unlock(&render_lock);
876                                 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++) {
877                                         if ((*vtt)->is_sync_client)     {
878                                                 if ((*vtt)->sync_countdown)     {
879                                                         (*vtt)->sync_countdown--;
880                                                 } else {
881                                                         (*vtt)->sync_countdown=(*vtt)->sync_cycles;
882                                                         (*vtt)->trigger();
883                                                 }
884                                         }
885                                 }
886                                 pthread_mutex_lock(&render_lock);
887                         }
888                         
889                         vtt=render_list.begin();
890                         for (vtt++; vtt!=render_list.end(); vtt++) {
891                                 (*vtt)->render();                                       
892                                 max=(*vtt)->max_value;
893                                 min=max;
894
895                                 for (sample=0, mix_sample=0; sample<(*vtt)->samples_in_outputbuffer; sample++) {
896                                         temp=(*vtt)->output_buffer[sample];
897                                         mix_buffer[mix_sample]+=temp*(*vtt)->res_volume_left;
898                                         mix_sample++;                                   
899                                         mix_buffer[mix_sample]+=temp*(*vtt)->res_volume_right;
900                                         mix_sample++;
901                                 
902                                         if (temp>max) max=temp;
903                                         else if (temp<min) min=temp;
904                                 }
905                                 
906                                 min*=-1.0;
907                                 if (min>max) (*vtt)->max_value=min; else (*vtt)->max_value=max;
908                                 
909                                 if ((*vtt)->ec_enable) {
910                                         for (sample=0, mix_sample=0; sample<(*vtt)->samples_in_outputbuffer; sample++) {
911                                                 temp=(*vtt)->ec_output_buffer[sample];
912                                                 
913                                                 mix_buffer[mix_sample]+=temp*(*vtt)->ec_volume_left;
914                                                 mix_sample++;
915                                                 mix_buffer[mix_sample]+=temp*(*vtt)->ec_volume_right;
916                                                 mix_sample++;
917                                         }
918                                 }
919                         }
920                         
921                         /* left */
922                         
923                         max=mix_max_l;
924                         min=max;
925
926                         for (sample=0; sample<samples_in_mix_buffer; sample+=2) {                               
927                                 temp=mix_buffer[sample];
928
929 #ifndef TX_DO_CLIP
930 #define FL_SHRT_MAX 32767.0
931 #define FL_SHRT_MIN -32768.0
932                                 if(temp < FL_SHRT_MIN) temp = FL_SHRT_MIN;
933                                 else if (temp > FL_SHRT_MAX) temp = FL_SHRT_MAX;
934 #endif                                  
935
936                                 mix_out_buffer[sample]=(int16_t) temp;
937                         
938                                 if (temp>max) max=temp;
939                                 else if (temp<min) min=temp;
940                         }
941                         
942                         min*=-1.0;
943                         if (min>max) mix_max_l=min; else mix_max_l=max;         
944                         
945                         /* right */
946                         
947                         max=mix_max_r;
948                         min=max;
949
950                         for (sample=1; sample<samples_in_mix_buffer; sample+=2) {                               
951                                 temp=mix_buffer[sample];
952
953 #ifndef TX_DO_CLIP
954                                 if(temp < FL_SHRT_MIN) temp = FL_SHRT_MIN;
955                                 else if (temp > FL_SHRT_MAX) temp = FL_SHRT_MAX;
956 #endif
957                                 
958                                 mix_out_buffer[sample]=(int16_t) temp;
959                         
960                                 if (temp>max) max=temp;
961                                 else if (temp<min) min=temp;
962                         }
963                         
964                         min*=-1.0;
965                         if (min>max) mix_max_r=min; else mix_max_r=max;         
966                         
967         }
968         master_triggered=0;
969                 
970         vtt=render_list.begin();
971         while (vtt!=render_list.end()) {
972                 next=vtt;
973                 next++;
974                 
975                 if ((*vtt)->want_stop) (*vtt)->stop_nolock();
976                 vtt=next;
977         }
978         pthread_mutex_unlock(&render_lock);
979         
980         return(mix_out_buffer);
981 }
982
983 void vtt_class :: forward_all_turntables()
984 {
985         list <vtt_class *> :: iterator vtt, next;
986
987         if (render_list.size()>0)
988         {
989                  vtt=render_list.begin();
990                  (*vtt)->forward_turntable();                    
991
992                  if (master_triggered)
993                  {
994                          for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
995                          {
996                                  if ((*vtt)->is_sync_client)
997                                  {
998                                          if ((*vtt)->sync_countdown)
999                                          {
1000                                                  (*vtt)->sync_countdown--;
1001                                          }
1002                                          else
1003                                          {
1004                                                  (*vtt)->sync_countdown=(*vtt)->sync_cycles;
1005                                                  (*vtt)->trigger();
1006                                          }
1007                                  }
1008                          }
1009                  }
1010
1011                  vtt=render_list.begin();
1012                  for (vtt++; vtt!=render_list.end(); vtt++)
1013                  {
1014                          (*vtt)->forward_turntable();
1015                  }
1016                  
1017         }
1018         master_triggered=0;
1019         vtt=render_list.begin();
1020         while (vtt!=render_list.end())
1021         {
1022                 next=vtt;
1023                 next++;
1024                 
1025                 if ((*vtt)->want_stop) (*vtt)->stop_nolock();
1026                 vtt=next;
1027         }
1028 }
1029
1030
1031 int vtt_class :: trigger()
1032 {
1033         list <vtt_fx *> :: iterator effect;
1034
1035         if (!buffer) return (1);
1036         
1037         if (!is_playing) pthread_mutex_lock(&render_lock);
1038         
1039         if (res_pitch>=0) pos_f=0;
1040         else pos_f=maxpos;
1041         fade=NEED_FADE_OUT;
1042         speed=res_pitch;
1043         speed_real=res_pitch;
1044         speed_target=res_pitch;
1045         want_stop=0;
1046
1047         /* activating plugins */
1048         for (effect=fx_list.begin(); effect != fx_list.end(); effect++)
1049         {
1050                 (*effect)->activate();
1051         }
1052
1053         max_value=0;
1054         
1055         if (is_sync_master)
1056         {
1057                 master_triggered=1;
1058                 master_triggered_at=0;
1059         }
1060         
1061         if (!is_playing)
1062         {
1063                 is_playing=1;
1064         
1065                 if (is_sync_master) 
1066                 {
1067                         render_list.push_front(this);           
1068                 }               
1069                 else
1070                 {
1071                         render_list.push_back(this);
1072                 }
1073                 pthread_mutex_unlock(&render_lock);
1074         }
1075         return(0);
1076 }
1077
1078 static bool do_unlock=true;
1079
1080 int vtt_class :: stop_nolock()
1081 {
1082         list <vtt_fx *> :: iterator effect;
1083
1084         if ((!is_playing) && do_unlock) {
1085                 pthread_mutex_unlock(&render_lock);
1086                 return(1);
1087         }
1088         render_list.remove(this);
1089         want_stop=0;
1090
1091         is_playing=0;
1092         max_value=0;
1093
1094         cleanup_vtt(this);
1095         //sync_countdown=0;
1096         
1097         /* deactivating plugins */
1098         for (effect=fx_list.begin(); effect != fx_list.end(); effect++) {
1099                 (*effect)->deactivate();
1100         }
1101         
1102         return(0);
1103 }
1104
1105 int vtt_class :: stop()
1106 {
1107         int res;
1108         
1109         pthread_mutex_lock(&render_lock);
1110
1111         do_unlock=false;
1112         
1113         res=stop_nolock();
1114
1115         do_unlock=true;
1116         
1117         pthread_mutex_unlock(&render_lock);
1118
1119         return(res);
1120 }
1121
1122 void vtt_class :: set_sync_master(int master)
1123 {
1124         if (master)
1125         {
1126                 if (sync_master) sync_master->set_sync_master(0);
1127                 sync_master=this;
1128                 is_sync_master=1;
1129         }
1130         else
1131         {
1132                 if (sync_master==this) sync_master=0;
1133                 is_sync_master=0;
1134                 gui_clear_master_button(this);
1135         }
1136 }
1137
1138 void vtt_class :: set_sync_client(int slave, int cycles)
1139 {
1140         tX_debug("vtt_class::set_sync_client() setting %i, %i.", slave, cycles);
1141         is_sync_client=slave;
1142         sync_cycles=cycles;
1143 //      sync_countdown=cycles; 
1144         sync_countdown=0;
1145 }
1146
1147 void vtt_class :: set_sync_client_ug(int slave, int cycles)
1148 {
1149         set_sync_client(slave, cycles);
1150 }
1151
1152 void vtt_class :: set_master_volume(f_prec new_volume)
1153 {
1154         list <vtt_class *> :: iterator vtt;
1155
1156         master_volume=new_volume;
1157         globals.volume=new_volume;
1158         
1159         if (main_list.size()>0)
1160         {
1161                 vol_channel_adjust=sqrt((f_prec) main_list.size());
1162                 res_master_volume=master_volume/vol_channel_adjust;             
1163         }
1164                 
1165         for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
1166         {
1167                 (*vtt)->recalc_volume();
1168         }
1169 }
1170
1171 void vtt_class :: set_master_pitch(f_prec new_pitch)
1172 {
1173         list <vtt_class *> :: iterator vtt;
1174         
1175         globals.pitch=new_pitch;
1176         for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
1177         {
1178                 (*vtt)->recalc_pitch();
1179         }
1180 }
1181
1182 void vtt_class :: focus_no(int no)
1183 {
1184         list <vtt_class *> :: iterator vtt;
1185         int i;
1186
1187         focused_vtt=NULL;
1188         
1189         for (i=0, vtt=main_list.begin(); vtt!=main_list.end(); vtt++, i++)
1190         {
1191                 if (i==no) {
1192                         focused_vtt=(*vtt);
1193                 }
1194         }
1195 }
1196
1197 void vtt_class :: focus_next()
1198 {
1199         list <vtt_class *> :: iterator vtt;
1200         
1201         if (!focused_vtt)
1202         {
1203                 if (main_list.size())
1204                 {
1205                         focused_vtt=(*main_list.begin());
1206                 }
1207                 return;
1208         }
1209         
1210         for (vtt=main_list.begin(); vtt!=main_list.end() ; vtt++) {
1211                 if ((*vtt)==focused_vtt) {
1212                         /* Ok, we found ourselves.. */
1213                         
1214                         vtt++;
1215                         while ((vtt!=main_list.end()) && ((*vtt)->audio_hidden) ) {
1216                                 vtt++;
1217                         }
1218                         
1219                         if (vtt==main_list.end()) {
1220                                 /* No other "focusable" after this vtt so we're looking for the next */
1221                                 
1222                                 for (vtt=main_list.begin(); vtt!=main_list.end() ; vtt++) {
1223                                         if (! (*vtt)->audio_hidden) {
1224                                                 focused_vtt=(*vtt);
1225                                                 return;
1226                                         }
1227                                 }
1228                                 /* When we get here there's no "focusable" vtt at all... damn */
1229                                 focused_vtt=NULL;
1230                                 return;
1231                         } else {
1232                                 focused_vtt=(*vtt);
1233                                 return;
1234                         }
1235                 }
1236         }
1237         
1238         focused_vtt=(*main_list.begin());
1239 }
1240
1241 void vtt_class :: set_scratch(int newstate)
1242 {
1243         if (newstate)
1244         {
1245                 sp_spin.receive_input_value(0);
1246                 do_scratch=1;
1247                 sense_cycles=globals.sense_cycles;
1248         }
1249         else
1250         {
1251                 sp_spin.receive_input_value(1);
1252                 do_scratch=0;
1253         }
1254 }
1255
1256
1257 void vtt_class :: unfocus()
1258 {
1259         focused_vtt=NULL;
1260 }
1261
1262 void vtt_class :: set_x_input_parameter(tX_seqpar *sp)
1263 {
1264         x_par = sp;
1265 }
1266
1267 void vtt_class :: set_y_input_parameter(tX_seqpar *sp)
1268 {
1269         y_par = sp;
1270 }
1271
1272 void vtt_class :: xy_input(f_prec x_value, f_prec y_value)
1273 {
1274         if (x_par) x_par->handle_mouse_input(x_value*globals.mouse_speed);
1275         if (y_par) y_par->handle_mouse_input(y_value*globals.mouse_speed);
1276 }
1277
1278 #define store(data); if (fwrite((void *) &data, sizeof(data), 1, output)!=1) res+=1;
1279
1280 int  vtt_class :: save(FILE *rc, gzFile rz, char *indent) {
1281         list <vtt_fx *> :: iterator effect;
1282         char tmp_xml_buffer[4096];
1283         
1284         int res=0;
1285
1286         tX_store("%s<turntable>\n", indent);
1287         strcat(indent, "\t");
1288         
1289         store_string("name", name);
1290         if (buffer) {
1291                 store_string("audiofile", filename);
1292         } else {
1293                 store_string("audiofile", "");
1294         }
1295         store_bool("sync_master", is_sync_master);
1296         store_bool("autotrigger", autotrigger);
1297         store_bool_sp("loop", loop, sp_loop);
1298
1299         store_bool_sp("sync_client", is_sync_client, sp_sync_client);
1300         store_int_sp("sync_cycles", sync_cycles, sp_sync_cycles);
1301
1302         store_float_sp("volume", rel_volume, sp_volume);
1303         store_float_sp("pitch", rel_pitch, sp_pitch);   
1304         store_bool_sp("mute", mute, sp_mute);
1305         store_float_sp("pan", pan, sp_pan);
1306         
1307         store_bool_sp("lowpass_enable", lp_enable, sp_lp_enable);
1308         store_float_sp("lowpass_gain", lp_gain, sp_lp_gain);
1309         store_float_sp("lowpass_reso", lp_reso, sp_lp_reso);
1310         store_float_sp("lowpass_freq", lp_freq, sp_lp_freq);
1311
1312         store_bool_sp("echo_enable", ec_enable, sp_ec_enable);
1313         store_float_sp("echo_length", ec_length, sp_ec_length);
1314         store_float_sp("echo_feedback", ec_feedback, sp_ec_feedback);
1315         store_float_sp("echo_pan", ec_pan, sp_ec_pan);
1316         store_float_sp("echo_volume", ec_volume, sp_ec_volume);
1317         
1318         store_id("speed", sp_speed.get_persistence_id());
1319         store_id("trigger", sp_trigger.get_persistence_id());
1320         store_id("spin", sp_spin.get_persistence_id());
1321
1322         
1323         if (x_par) {
1324                 store_int("x_axis_mapping", x_par->get_persistence_id());
1325         }
1326         
1327         if (y_par) {
1328                 store_int("y_axis_mapping", y_par->get_persistence_id());
1329         }
1330
1331         store_bool("audio_panel_hidden", audio_hidden);
1332         store_bool("control_panel_hidden", control_hidden);
1333         store_bool("main_panel_hidden", gui.main_panel->is_hidden());
1334         store_bool("trigger_panel_hidden", gui.trigger_panel->is_hidden());
1335         store_bool("lowpass_panel_hidden", gui.lp_panel->is_hidden());
1336         store_bool("echo_panel_hidden", gui.ec_panel->is_hidden());
1337         
1338         store_bool("mix_mute", mix_mute);
1339         store_bool("mix_solo", mix_solo);
1340
1341         store_float("audio_x_zoom", gui_get_audio_x_zoom(this));
1342         
1343         tX_store("%s<fx>\n", indent);
1344         strcat(indent, "\t");
1345         
1346         for (effect=fx_list.begin(); effect!=fx_list.end(); effect++) {
1347                 (*effect)->save(rc, rz, indent);
1348         }
1349         indent[strlen(indent)-1]=0;
1350         tX_store("%s</fx>\n", indent);
1351         
1352         indent[strlen(indent)-1]=0;
1353         tX_store("%s</turntable>\n", indent);
1354         
1355         return(res);
1356 }
1357
1358 #define TX_XML_SETFILE_VERSION "1.0"
1359
1360 int  vtt_class :: save_all(FILE* rc, gzFile rz) {
1361         int res=0;
1362         list <vtt_class *> :: iterator vtt;
1363         char indent[256];
1364         
1365         tX_seqpar :: create_persistence_ids();
1366
1367         tX_store("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n");
1368         tX_store("<terminatorXset version=\"%s\">\n", TX_XML_SETFILE_VERSION);
1369         
1370         strcpy(indent, "\t");
1371
1372         //store_int(vtt_amount); obsolete
1373
1374         store_float_sp("master_volume", master_volume, sp_master_volume);
1375         store_float_sp("master_pitch", globals.pitch, sp_master_pitch);
1376
1377         for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++) {
1378                 res+=(*vtt)->save(rc, rz, indent);
1379         }
1380         
1381         sequencer.save(rc, rz, indent);
1382         
1383         tX_store("</terminatorXset>\n");
1384         
1385         return(res);
1386 }
1387
1388 int vtt_class :: load(xmlDocPtr doc, xmlNodePtr node) {
1389         char buffer[1024];
1390         bool hidden;
1391         int xpar_id=-1;
1392         int ypar_id=-1;
1393         int elementFound;
1394         char *pid_attr;
1395         int pid;
1396         double dvalue;
1397         double tmp;
1398         char tmp_xml_buffer[4096];
1399         
1400         for (xmlNodePtr cur=node->xmlChildrenNode; cur != NULL; cur = cur->next) {
1401                 if (cur->type == XML_ELEMENT_NODE) {
1402                         elementFound=0;
1403                         
1404                         restore_string_ac("name", buffer, set_name(buffer));
1405                         restore_string("audiofile", filename);
1406                         restore_bool("sync_master", is_sync_master);
1407                         restore_bool("autotrigger", autotrigger);
1408                         restore_bool_id("loop", loop, sp_loop, nop);
1409                         restore_bool_id("sync_client", is_sync_client, sp_sync_client, set_sync_client(is_sync_client, sync_cycles));
1410                         restore_int_id("sync_cycles", sync_cycles, sp_sync_cycles, set_sync_client(is_sync_client, sync_cycles));
1411                         restore_float_id("volume", rel_volume, sp_volume, recalc_volume());
1412                         restore_float_id("pitch", rel_pitch, sp_pitch, recalc_pitch());
1413                         restore_bool_id("mute", mute, sp_mute, set_mute(mute));
1414                         restore_float_id("pan", pan, sp_pan, set_pan(pan));
1415         
1416                         restore_bool_id("lowpass_enable", lp_enable, sp_lp_enable, lp_set_enable(lp_enable));
1417                         restore_float_id("lowpass_gain", lp_gain, sp_lp_gain, lp_set_gain(lp_gain)); 
1418                         restore_float_id("lowpass_reso", lp_reso, sp_lp_reso, lp_set_reso(lp_reso));
1419                         restore_float_id("lowpass_freq", lp_freq, sp_lp_freq, lp_set_freq(lp_freq));
1420         
1421                         restore_bool_id("echo_enable", ec_enable, sp_ec_enable, ec_set_enable(ec_enable));      
1422                         restore_float_id("echo_length", ec_length, sp_ec_length, ec_set_length(ec_length));
1423                         restore_float_id("echo_feedback", ec_feedback, sp_ec_feedback, ec_set_feedback(ec_feedback));
1424                         restore_float_id("echo_pan", ec_pan, sp_ec_pan, ec_set_pan(ec_pan));
1425                         restore_float_id("echo_volume", ec_volume, sp_ec_volume, ec_set_volume(ec_volume));             
1426                 
1427                         restore_id("speed", sp_speed);  
1428                         restore_id("trigger", sp_trigger);
1429                         restore_id("spin", sp_spin);
1430         
1431                         restore_int("x_axis_mapping", xpar_id);
1432                         restore_int("y_axis_mapping", ypar_id);
1433                         
1434                         restore_bool("mix_mute", mix_mute);
1435                         restore_bool("mix_solo", mix_solo);
1436         
1437                         restore_bool("audio_panel_hidden", audio_hidden);
1438                         restore_bool("control_panel_hidden", control_hidden);
1439                         restore_bool_ac("main_panel_hidden", hidden, gui.main_panel->hide(hidden));
1440                         restore_bool_ac("trigger_panel_hidden", hidden, gui.trigger_panel->hide(hidden));
1441                         restore_bool_ac("lowpass_panel_hidden", hidden, gui.lp_panel->hide(hidden));                    
1442                         restore_bool_ac("echo_panel_hidden", hidden, gui.ec_panel->hide(hidden));
1443                         restore_float_ac("audio_x_zoom", tmp, gui_set_audio_x_zoom(this,tmp));
1444                         vg_adjust_zoom(gui.zoom, this);
1445                         
1446                         if (xmlStrcmp(cur->name, (xmlChar *) "fx")==0) {
1447                                 xmlNodePtr fx=cur;
1448                                 elementFound=1;
1449                                 
1450                                 for (xmlNodePtr cur=fx->xmlChildrenNode; cur != NULL; cur = cur->next) {
1451                                         if (cur->type == XML_ELEMENT_NODE) {
1452                                                 int elementFound=0;
1453                                                 
1454                                                 if (xmlStrcmp(cur->name, (xmlChar *) "cutoff")==0) {
1455                                                         for (unsigned int t=0; t<fx_list.size(); t++) effect_down(lp_fx);
1456                                                         elementFound=1;
1457                                                 } else if (xmlStrcmp(cur->name, (xmlChar *) "lowpass")==0) {
1458                                                         for (unsigned int t=0; t<fx_list.size(); t++) effect_down(ec_fx);
1459                                                         elementFound=1;                                                         
1460                                                 } else if (xmlStrcmp(cur->name, (xmlChar *) "ladspa_plugin")==0) {
1461                                                         xmlNodePtr pluginNode=cur;
1462                                                         int ladspa_id=-1;
1463                                                         elementFound=1;
1464                                                         
1465                                                         for (xmlNodePtr cur=pluginNode->xmlChildrenNode; cur!=NULL; cur = cur->next) {
1466                                                                 int elementFound;
1467                                                                 if (cur->type == XML_ELEMENT_NODE) {
1468                                                                         elementFound=0;
1469
1470                                                                         restore_int("ladspa_id", ladspa_id);
1471                                                                         if (elementFound) break;
1472                                                                 }
1473                                                         }
1474                                                         
1475                                                         if (ladspa_id!=-1) {
1476                                                                 LADSPA_Plugin *plugin=LADSPA_Plugin::getPluginByUniqueID(ladspa_id);
1477                                                                 if (plugin) {
1478                                                                         vtt_fx_ladspa *ladspa_effect=add_effect(plugin);
1479                                                                         ladspa_effect->load(doc, pluginNode);
1480                                                                 } else {
1481                                                                         sprintf(buffer,"The terminatorX set file you are loading makes use of a LADSPA plugin that is not installed on this machine. The plugin's ID is [%i].", ladspa_id);
1482                                                                         tx_note(buffer, true);                                                  
1483                                                                 }
1484                                                         } else {
1485                                                                 tX_warning("ladspa_plugin section without a ladspa_id element.");
1486                                                         }
1487                                                         
1488                                                 } else {
1489                                                         tX_warning("unhandled element %s in fx section.", cur->name);
1490                                                 }
1491                                         }
1492                                 }
1493                         }
1494                         
1495                         if(!elementFound) {
1496                                 tX_warning("unhandled element %s in turntable secion.", cur->name);
1497                         }
1498                 }
1499         }
1500
1501         recalc_volume();
1502
1503         if (mix_solo) {
1504                 solo_ctr++;
1505         }
1506         
1507         if (xpar_id>=0) {
1508                 set_x_input_parameter(tX_seqpar :: get_sp_by_persistence_id(xpar_id));
1509         }
1510         else set_x_input_parameter(NULL);
1511         
1512         if (ypar_id) {
1513                 set_y_input_parameter(tX_seqpar :: get_sp_by_persistence_id(ypar_id));
1514         }
1515         else set_y_input_parameter(NULL);
1516         
1517         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gui.mute), mix_mute);
1518         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gui.solo), mix_solo);
1519         
1520         return 0;
1521 }
1522
1523 void vtt_class :: delete_all()
1524 {
1525         while (main_list.size()) {
1526                 delete((*main_list.begin()));
1527         }
1528         
1529         /* Take care of the master events.. */
1530         sequencer.delete_all_events(tX_sequencer::DELETE_ALL);
1531         
1532         /* Now reset master settings ot the default: */
1533         set_master_pitch(1.0);
1534         set_master_volume(1.0);
1535         
1536         sp_master_pitch.do_exec(1.0);
1537         sp_master_pitch.do_update_graphics();
1538
1539         sp_master_volume.do_exec(1.0);
1540         sp_master_volume.do_update_graphics();
1541         
1542         /* Remove master MIDI mappings... */
1543         sp_master_pitch.bound_midi_event.type=tX_midievent::NONE;
1544         sp_master_volume.bound_midi_event.type=tX_midievent::NONE;
1545         
1546         seq_update();
1547 }
1548
1549
1550 int vtt_class :: load_all(xmlDocPtr doc, char *fname) {
1551         xmlNodePtr root=xmlDocGetRootElement(doc);
1552         int elementFound=0;
1553         char fn_buff[4096];
1554         double dvalue;
1555         int res=0;
1556         int restmp=0;
1557         
1558         if (!root) {
1559                 tX_error("no root element? What kind of XML document is this?");
1560                 return 1;
1561         }
1562         
1563         if (xmlStrcmp(root->name, (const xmlChar *) "terminatorXset")) {
1564                 tX_error("this is not a terminatorXset file.")
1565                 return 2;
1566         }
1567         
1568         if (xmlGetProp(root,(xmlChar *) "version")==NULL) {
1569                 tX_error("the set file lacks a version attribute.");
1570                 return 3;
1571         }
1572         
1573         if (xmlStrcmp(xmlGetProp(root, (xmlChar *) "version"), (xmlChar *) TX_XML_SETFILE_VERSION)) {
1574                 tX_warning("this set file is version %s - while this releases uses version %s - trying to load anyway.", xmlGetProp(root, (xmlChar *) "version"), TX_XML_SETFILE_VERSION);
1575         }
1576         
1577         /* delete current tables... */
1578         delete_all();
1579
1580         int table_ctr=0;
1581         
1582         /* counting turntables.. */
1583         for (xmlNodePtr cur=root->xmlChildrenNode; cur != NULL; cur = cur->next) {
1584                 if (cur->type == XML_ELEMENT_NODE) {    
1585                         if (xmlStrcmp(cur->name, (xmlChar *) "turntable")==0) {
1586                                 table_ctr++;
1587                         }
1588                 }
1589         }
1590
1591         tX_debug("Found %i turntables in set.",  table_ctr);
1592
1593         ld_create_loaddlg(TX_LOADDLG_MODE_MULTI, table_ctr);
1594         ld_set_setname(fname);
1595
1596         /* parsing all */
1597         for (xmlNodePtr cur=root->xmlChildrenNode; cur != NULL; cur = cur->next) {
1598                 if (cur->type == XML_ELEMENT_NODE) {                    
1599                         elementFound=0;
1600                 
1601                         restore_float_id("master_volume", master_volume, sp_master_volume, set_master_volume(master_volume));
1602                         restore_float_id("master_pitch", globals.pitch, sp_master_pitch, set_master_pitch(globals.pitch));
1603                         
1604                         if ((!elementFound) && (xmlStrcmp(cur->name, (xmlChar *) "turntable")==0)) {
1605                                 elementFound=1;
1606                                 vtt_class *vtt=new vtt_class(1);
1607                                 vtt->load(doc, cur);
1608                                 
1609                                 tX_debug("loading a turntable..");
1610
1611                                 if (strlen(vtt->filename)) {
1612                                         strcpy(fn_buff, vtt->filename);
1613                                         ld_set_filename(fn_buff);
1614                                 
1615                                         restmp=(int) vtt->load_file(fn_buff);
1616                                         res+=restmp;
1617                                 }
1618         
1619                                 gtk_box_pack_start(GTK_BOX(control_parent), vtt->gui.control_box, TRUE, TRUE, 0);
1620                                 gtk_box_pack_start(GTK_BOX(audio_parent), vtt->gui.audio_box, TRUE, TRUE, 0);
1621                                 if (vtt->audio_hidden) vtt->hide_audio(vtt->audio_hidden);
1622                                 if (vtt->control_hidden) vtt->hide_control(vtt->control_hidden);\r
1623                         }
1624                         if ((!elementFound) && (xmlStrcmp(cur->name, (xmlChar *) "sequencer")==0)) {
1625                                 elementFound=1;
1626                                 sequencer.load(doc, cur);
1627                         }
1628                         if (!elementFound) {
1629                                 tX_warning("unhandled element %s in setfile %s", cur->name, fname);
1630                         }
1631                 }
1632         }
1633         
1634         sp_master_volume.do_update_graphics();
1635         sp_master_pitch.do_update_graphics();
1636         
1637         ld_destroy();
1638         
1639         return(res);
1640 }
1641
1642 void add_vtt(GtkWidget *ctrl, GtkWidget *audio, char *fn)
1643 {
1644         vtt_class *hmmpg;
1645         hmmpg = new vtt_class(1);
1646         gtk_box_pack_start(GTK_BOX(ctrl), hmmpg->gui.control_box, TRUE, TRUE, 0);
1647         gtk_box_pack_start(GTK_BOX(audio), hmmpg->gui.audio_box, TRUE, TRUE, 0);
1648         if (fn) hmmpg->load_file(fn);
1649 }
1650
1651 extern void vg_move_fx_panel_up(GtkWidget *wid, vtt_class *vtt);
1652 extern void vg_move_fx_panel_down(GtkWidget *wid, vtt_class *vtt);
1653
1654 //#define debug_fx_stack(); for (i=fx_list.begin(); i != fx_list.end(); i++) puts((*i)->get_info_string());
1655 #define debug_fx_stack();
1656
1657 void vtt_class :: effect_up(vtt_fx *effect)
1658 {
1659         list <vtt_fx *> :: iterator i;
1660         list <vtt_fx *> :: iterator previous;
1661         int ok=0;
1662         
1663         debug_fx_stack();
1664         
1665         if ((*fx_list.begin())==effect) return;
1666         
1667         for (previous=i=fx_list.begin(); i != fx_list.end(); i++)
1668         {
1669                 if ((*i) == effect)
1670                 {
1671                         ok=1;
1672                         break;
1673                 }
1674                 previous=i;
1675         }
1676         
1677         if (ok)
1678         {       
1679                 pthread_mutex_lock(&render_lock);
1680                 fx_list.remove(effect);
1681                 fx_list.insert(previous, effect);
1682                 pthread_mutex_unlock(&render_lock);
1683
1684                 vg_move_fx_panel_up(effect->get_panel_widget(), this);
1685         }
1686         
1687         debug_fx_stack();
1688 }
1689
1690 void vtt_class :: effect_down(vtt_fx *effect)
1691 {
1692         list <vtt_fx *> :: iterator i;
1693         int ok=0;
1694
1695         debug_fx_stack();
1696                 
1697         for (i=fx_list.begin(); i != fx_list.end(); i++)
1698         {
1699                 if ((*i) == effect)
1700                 {
1701                         ok=1;
1702                         break;
1703                 }
1704         }
1705         
1706         if ((ok) && (i!=fx_list.end()))
1707         {
1708                 i++;
1709                 if (i==fx_list.end()) return;
1710                 i++;
1711
1712                 pthread_mutex_lock(&render_lock);
1713                 fx_list.remove(effect);
1714                 
1715                 fx_list.insert(i, effect);
1716                 vg_move_fx_panel_down(effect->get_panel_widget(), this);
1717                 pthread_mutex_unlock(&render_lock);
1718         }
1719         
1720 debug_fx_stack();       
1721 }
1722
1723 void vtt_class ::  effect_remove(vtt_fx_ladspa *effect)
1724 {
1725         pthread_mutex_lock(&render_lock);
1726         fx_list.remove(effect);
1727         pthread_mutex_unlock(&render_lock);
1728         
1729         delete effect;
1730 }
1731
1732 extern void gui_hide_control_panel(vtt_class *vtt, bool hide);
1733 extern void gui_hide_audio_panel(vtt_class *vtt, bool hide);
1734
1735 void vtt_class :: hide_audio(bool hide) {
1736         audio_hidden=hide;
1737         gui_hide_audio_panel(this, hide);
1738 }
1739
1740 void vtt_class :: hide_control(bool hide) {
1741         control_hidden=hide;
1742         gui_hide_control_panel(this, hide);     
1743 }
1744
1745 void vtt_class :: set_sample_rate(int samplerate) {
1746         list <vtt_class *> :: iterator vtt;
1747         double sr=(double) samplerate;
1748
1749         last_sample_rate=samplerate;
1750         
1751         for (vtt=main_list.begin(); vtt!=main_list.end() ; vtt++) {
1752                 if ((*vtt)->audiofile) {
1753                         double file_rate=(*vtt)->audiofile->get_sample_rate();
1754                         (*vtt)->audiofile_pitch_correction=file_rate/sr;
1755                 } else {
1756                         (*vtt)->audiofile_pitch_correction=1.0;
1757                 }
1758                 (*vtt)->recalc_pitch();
1759         }
1760         
1761         int no_samples=(int) (sr*0.001); // Forcing 1 ms blocksize
1762         
1763         set_mix_buffer_size(no_samples);        
1764 }
1765
1766 void vtt_class :: adjust_to_master_pitch(int master_cycles, int cycles, bool create_event) {
1767         if (!sync_master) return;
1768         if (this==sync_master) return;
1769         if (!sync_master->audiofile) return;
1770         if (!audiofile) return;
1771         
1772         double master_time=((double) master_cycles)/sync_master->rel_pitch*sync_master->audiofile->get_no_samples()/((double) sync_master->audiofile->get_sample_rate());
1773         double my_rel_pitch=((audiofile->get_no_samples()/((double) audiofile->get_sample_rate()))*((double) cycles))/master_time;
1774         
1775         if (create_event) {
1776                 sp_pitch.do_exec(my_rel_pitch);
1777                 sp_pitch.record_value(my_rel_pitch);
1778         } else {
1779                 sp_pitch.do_exec(my_rel_pitch);
1780         }
1781         
1782         tX_debug("master_time: %lf, res_pitch: %lf - res time: %lf, (%lf, %lf)", master_time, my_rel_pitch, ((double) cycles)*my_rel_pitch*audiofile->get_no_samples()/((double) audiofile->get_sample_rate()), (double) sync_master->audiofile->get_sample_rate(),(double)  audiofile->get_sample_rate());
1783         
1784         sp_pitch.update_graphics();
1785 }