a659c1332348def75102587a69c83335c1524bfb
[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 f_prec vtt_class::saturate_fac=0.1;
87 int vtt_class::do_saturate=0;
88 vtt_class * vtt_class::sync_master=NULL;
89 int vtt_class::master_triggered=0;
90 int vtt_class::master_triggered_at=0;
91 vtt_class * vtt_class::focused_vtt=NULL;
92 f_prec vtt_class::mix_max_l=0;
93 f_prec vtt_class::mix_max_r=0;
94 f_prec vtt_class::vol_channel_adjust=1.0;
95 int vtt_class::mix_buffer_size=0;
96
97 #define GAIN_AUTO_ADJUST 0.8
98
99 vtt_class :: vtt_class (int do_create_gui)
100 {       
101         vtt_amount++;
102         sprintf (name, "Turntable %i", vtt_amount);
103         strcpy(filename, "NONE");
104         buffer=NULL;
105         samples_in_buffer=0;
106         pos_i_max=0;
107
108         pan=0;
109         rel_pitch=1; 
110         ec_volume=1; 
111         ec_pan=1; 
112         audiofile_pitch_correction=1.0;
113         ec_length=1;
114         ec_output_buffer=NULL;
115         output_buffer=NULL;
116         
117         set_volume(1);
118         set_pitch(1);
119         
120         autotrigger=1;
121         loop=1;
122         
123         is_playing=0;
124         is_sync_master=0;
125         is_sync_client=0;
126         sync_cycles=0,
127         sync_countdown=0;
128         
129         lp_enable=0;
130         lp_reso=0.8;
131         lp_freq=0.3;
132         lp_gain=1;
133         lp_setup(lp_gain, lp_reso, lp_freq);
134         lp_reset();
135         
136         ec_enable=0;
137         ec_length=0.5;
138         ec_feedback=0.3;
139         ec_clear_buffer();
140         ec_set_length(0.5);
141         ec_set_pan(0);
142         ec_set_volume(1);
143         
144         main_list.push_back(this);
145
146         /* "connecting" the seq-parameters */
147         
148         sp_speed.set_vtt((void *) this);
149         sp_volume.set_vtt((void *) this);       
150         sp_pitch.set_vtt((void *) this);        
151         sp_pan.set_vtt((void *) this);
152         sp_trigger.set_vtt((void *) this);      
153         sp_loop.set_vtt((void *) this); 
154         sp_sync_client.set_vtt((void *) this);  
155         sp_sync_cycles.set_vtt((void *) this);  
156         sp_lp_enable.set_vtt((void *) this);    
157         sp_lp_gain.set_vtt((void *) this);      
158         sp_lp_reso.set_vtt((void *) this);      
159         sp_lp_freq.set_vtt((void *) this);      
160         sp_ec_enable.set_vtt((void *) this);    
161         sp_ec_length.set_vtt((void *) this);
162         sp_ec_pan.set_vtt((void *) this);
163         sp_ec_volume.set_vtt((void *) this);
164         sp_ec_feedback.set_vtt((void *) this);          
165         sp_mute.set_vtt((void *) this);
166         sp_spin.set_vtt((void *) this);
167
168         x_par = &sp_speed;
169         y_par = &sp_lp_freq;
170         
171         lp_fx=new vtt_fx_lp();
172         lp_fx->set_vtt((void *) this);
173         fx_list.push_back(lp_fx);
174
175         ec_fx=new vtt_fx_ec();
176         ec_fx->set_vtt((void *) this);
177         fx_list.push_back(ec_fx);
178         
179         if (do_create_gui)
180         {       
181                 build_vtt_gui(this);
182                 lp_fx->set_panel_widget(gui.lp_panel->get_widget());    
183                 ec_fx->set_panel_widget(gui.ec_panel->get_widget());
184         }
185         else have_gui=0;
186                 
187         set_pan(0);     
188         set_master_volume(globals.volume);
189         set_output_buffer_size(samples_in_mix_buffer/2);
190         
191         audiofile = NULL;
192         audiofile_pitch_correction=1.0;
193         mute=0;
194         mix_solo=0;
195         mix_mute=0;
196         res_mute=mute;
197         res_mute_old=0;
198         
199         audio_hidden=false;
200         control_hidden=false;
201         
202         do_scratch=0;
203         speed_last=1;
204         speed_real=1;\r
205 }
206
207 vtt_class :: ~vtt_class()
208 {
209         vtt_fx *effect;
210         stop();
211
212         main_list.remove(this);
213         if (audiofile) delete audiofile;
214         //if (buffer) free(buffer);
215         if (output_buffer) tX_freemem(output_buffer, "output_buffer", "vtt Destructor");
216         vtt_amount--;
217         
218         while (fx_list.size())
219         { 
220                 effect=(*fx_list.begin());
221                 fx_list.remove(effect);
222                 delete effect;
223         }
224         
225         if (sync_master==this) {
226                 sync_master=NULL;
227         }
228         
229         delete_gui(this);
230 }
231
232 void vtt_class :: set_name(char *newname)
233 {
234         strcpy(name, newname);
235         gui_set_name(this, name);       
236 }
237
238 tX_audio_error vtt_class :: load_file(char *fname)
239 {
240         tX_audio_error res;
241         int was_playing=is_playing;
242         
243         if (is_playing) stop();
244
245         if (audiofile) delete(audiofile);
246         
247         buffer=NULL;
248         samples_in_buffer=0;
249         maxpos=0;
250         pos_i_max=0;
251         strcpy(filename,"");
252
253         audiofile=new tx_audiofile();
254         res=audiofile->load(fname);     
255         
256         if (res==TX_AUDIO_SUCCESS) {
257                 buffer=audiofile->get_buffer();
258                 double file_rate=audiofile->get_sample_rate();
259                 audiofile_pitch_correction=file_rate/((double) last_sample_rate);
260                 recalc_pitch();
261                 samples_in_buffer=audiofile->get_no_samples();
262                 pos_i_max=samples_in_buffer-1;
263                 maxpos=audiofile->get_no_samples();
264                 strcpy(filename, fname);
265                 if (was_playing) trigger();
266 //              printf("Successfully loaded %s, %08x, %i\n", fname, buffer, samples_in_buffer);
267         }
268         
269         if (have_gui)
270         {
271                 gui_update_display(this);
272         }
273         ec_set_length(ec_length);
274         
275         return(res);
276 }
277
278 int vtt_class :: set_output_buffer_size(int newsize)
279 {
280         list <vtt_fx *> :: iterator effect;
281
282         if (ec_output_buffer) tX_freemem(ec_output_buffer, "ec_output_buffer", "vtt set_output_buffer_size()");
283         tX_malloc(ec_output_buffer, "ec_output_buffer", "vtt set_output_buffer_size()", sizeof(float)*newsize, (float *));
284
285         if (output_buffer) tX_freemem(output_buffer, "output_buffer", "vtt set_output_buffer_size()");
286         tX_malloc(output_buffer, "output_buffer", "vtt set_output_buffer_size()", sizeof(float)*newsize, (float *));
287
288         end_of_outputbuffer = output_buffer + newsize; //size_t(sizeof(float)*(newsize));
289         
290         samples_in_outputbuffer=newsize;
291         inv_samples_in_outputbuffer=1.0/samples_in_outputbuffer;
292
293         for (effect=fx_list.begin(); effect != fx_list.end(); effect++)
294         {
295                 (*effect)->reconnect_buffer();
296         }
297         
298         if (output_buffer) return(0);   
299         else return(0);
300 }
301
302 void vtt_class :: set_volume(f_prec newvol)
303 {
304         rel_volume=newvol;
305         recalc_volume();
306 }
307
308 void vtt_class :: recalc_volume()
309 {
310         res_volume=rel_volume*res_master_volume;
311         f_prec ec_res_volume=res_volume*ec_volume;
312         
313         if (pan>0.0)
314         {
315                 res_volume_left=(1.0-pan)*res_volume;
316                 res_volume_right=res_volume;
317         }
318         else if (pan<0.0)
319         {
320                 res_volume_left=res_volume;
321                 res_volume_right=(1.0+pan)*res_volume;
322         }
323         else
324         {
325                 res_volume_left=res_volume_right=res_volume;
326         }
327         
328         if (ec_pan>0.0)
329         {
330                 ec_volume_left=(1.0-ec_pan)*ec_res_volume;
331                 ec_volume_right=ec_res_volume;
332         }
333         else if (ec_pan<0.0)
334         {
335                 ec_volume_left=ec_res_volume;
336                 ec_volume_right=(1.0+ec_pan)*ec_res_volume;
337         }
338         else
339         {
340                 ec_volume_left=ec_volume_right=ec_res_volume;
341         }       
342 //      printf("vtt_volume: %f, %f, l: %f, r: %f\n", rel_volume, res_volume, res_volume_left, res_volume_right);
343 }
344
345 void vtt_class :: set_pan(f_prec newpan)
346 {
347         pan=newpan;
348         recalc_volume();
349 }
350
351 void vtt_class :: set_pitch(f_prec newpitch)
352 {
353         rel_pitch=newpitch;
354         recalc_pitch();
355 }
356
357 void vtt_class :: recalc_pitch()
358 {
359         res_pitch=globals.pitch*rel_pitch;
360         res_pitch*=audiofile_pitch_correction;
361         speed=res_pitch;
362         ec_set_length(ec_length);
363 }
364
365 void vtt_class :: set_autotrigger(int newstate)
366 {
367         autotrigger=newstate;
368 }
369
370 void vtt_class :: set_loop(int newstate)
371 {
372         loop=newstate;
373 }
374
375 void vtt_class :: set_mute(int newstate)
376 {
377         mute=newstate;
378         calc_mute();
379 }
380
381 void vtt_class :: set_mix_mute(int newstate)
382 {
383         mix_mute=newstate;
384         calc_mute();
385 }
386
387 void vtt_class :: set_mix_solo(int newstate)
388 {
389         if (mix_solo && !newstate)
390         {
391                 /* turning it off */
392                 mix_solo=0;
393                 solo_ctr--;
394         }
395         else if (!mix_solo && newstate)
396         {
397                 /* turning it on */
398                 mix_solo=1;
399                 solo_ctr++;
400         }
401         calc_mute();
402
403         /* locking ? */
404         list <vtt_class *> :: iterator vtt;
405         
406         for (vtt=main_list.begin(); vtt!=main_list.end() ; vtt++)
407         {
408                 (*vtt)->calc_mute();
409         }
410 }
411
412 void vtt_class :: lp_set_enable (int newstate)
413 {
414         lp_enable=newstate;
415         lp_reset();
416 }
417
418 void vtt_class :: lp_reset()
419 {
420         lp_buf0=lp_buf1=0;
421 }
422
423 void vtt_class :: lp_set_gain (f_prec gain)
424 {
425         lp_gain=gain;
426         lp_resgain=lp_gain*lp_autogain;
427 }
428
429 void vtt_class :: lp_set_reso(f_prec reso)
430 {
431         lp_reso=reso;
432         
433         lp_b=reso*(1.0+(1.0/lp_a));
434         lp_autogain=1.0-reso*GAIN_AUTO_ADJUST;
435         lp_resgain=lp_gain*lp_autogain;
436 }
437
438 void vtt_class :: lp_set_freq(f_prec freq)
439 {
440         lp_freq=freq;
441         
442         lp_a=0.9999-freq;
443         lp_b=lp_reso*(1.0+(1.0/lp_a));
444 }
445
446 void vtt_class :: lp_setup(f_prec gain, f_prec reso, f_prec freq)
447 {
448         lp_freq=freq;
449         lp_reso=reso;
450         
451         lp_a=1.0-freq;
452         lp_b=reso*(1.0+(1.0/lp_a));
453         
454         lp_autogain=1.0-reso*GAIN_AUTO_ADJUST;
455         lp_resgain=lp_gain*lp_autogain;
456 }
457
458 void vtt_class :: ec_set_enable(int newstate)
459 {
460         ec_enable=newstate;
461         ec_clear_buffer();
462 }
463
464
465 void vtt_class :: ec_set_pan(f_prec pan)
466 {
467         ec_pan=pan;
468
469         recalc_volume();
470 }
471
472 /* Max length is 1.0 */
473
474 void vtt_class :: ec_set_length(f_prec length)
475 {
476         int delay;
477
478         ec_length=length;
479         if (res_pitch==0) 
480         {
481                 ec_res_length=length*samples_in_buffer;
482         }
483         else
484         {
485                 ec_res_length=length*samples_in_buffer/res_pitch;       
486         }
487         
488         if (ec_res_length<0) ec_res_length*=-1;
489         
490         if (ec_res_length>=EC_MAX_BUFFER)
491         {
492                 ec_res_length=EC_MAX_BUFFER*length;
493         }
494         
495         delay=(int )floor(ec_res_length);
496         delay-=2;
497         ec_delay=&ec_buffer[delay];
498 }
499
500 void vtt_class :: ec_set_feedback(f_prec feedback)
501 {
502         ec_feedback=feedback;
503 }
504
505
506 void vtt_class :: ec_set_volume(f_prec volume)
507 {
508         ec_volume=volume;
509         recalc_volume();
510 }
511
512 void vtt_class :: ec_clear_buffer()
513 {
514         f_prec *ptr;
515         
516         for (ptr=ec_buffer; ptr<=ec_delay; ptr++) {
517                 *ptr=0.0;
518         }
519         ec_ptr=ec_buffer;
520 }
521
522 void vtt_class :: render()
523 {
524         list <vtt_fx *> :: iterator effect;
525
526         if (do_scratch) {
527                 if (sense_cycles>0) {
528                         sense_cycles--;
529                         if (sense_cycles==0) sp_speed.receive_input_value(0);
530                 }
531         }
532         render_scratch();
533         
534         for (effect=fx_list.begin(); effect != fx_list.end(); effect++) {
535                 if ((*effect)->isEnabled()) (*effect)->run();
536         }
537 }
538
539 extern void vg_create_fx_gui(vtt_class *vtt, vtt_fx_ladspa *effect, LADSPA_Plugin *plugin);
540
541 vtt_fx_ladspa * vtt_class :: add_effect (LADSPA_Plugin *plugin)
542 {
543         vtt_fx_ladspa *new_effect;
544         
545         new_effect = new vtt_fx_ladspa (plugin, this);
546         pthread_mutex_lock(&render_lock);
547         fx_list.push_back(new_effect);
548         if (is_playing) new_effect->activate();
549         pthread_mutex_unlock(&render_lock);
550         vg_create_fx_gui(this, new_effect, plugin);
551         
552         return new_effect;
553 }
554
555 void vtt_class :: calc_speed()
556 {
557         do_mute=0;
558         fade_out=0;
559         fade_in=0;
560
561         if (speed != speed_target) {
562                 speed_target=speed;
563                 speed_step=speed_target-speed_real;
564                 speed_step/=globals.vtt_inertia;
565                 tX_error("dingens - step: %lf", speed_step);
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         {
817                 res|=(*vtt)->set_output_buffer_size(no_samples);
818         }
819         
820         if ((!mix_buffer) || (!mix_out_buffer) || res) return(1);
821         
822         mix_buffer_size=no_samples;
823         
824         return(0);
825 }
826
827 int16_t * vtt_class :: render_all_turntables()
828 {
829         list <vtt_class *> :: iterator vtt, next;
830         int sample;
831         int mix_sample;
832         f_prec temp;
833         f_prec max;
834         f_prec min;
835         
836         pthread_mutex_lock(&render_lock);
837         
838         if (render_list.size()==0)
839         {
840                 for (sample=0; sample<samples_in_mix_buffer; sample++)
841                 {
842                         mix_out_buffer[sample]=0;
843                 }
844         }
845         else
846         {
847                         vtt=render_list.begin();
848                         (*vtt)->render();                       
849                         max=(*vtt)->max_value;
850                         min=max;
851
852                         for (sample=0, mix_sample=0; sample<(*vtt)->samples_in_outputbuffer; sample++)
853                         {                               
854                                 temp=(*vtt)->output_buffer[sample];
855                                 mix_buffer[mix_sample]=temp*(*vtt)->res_volume_left;
856                                 mix_sample++;
857                                 mix_buffer[mix_sample]=temp*(*vtt)->res_volume_right;
858                                 mix_sample++;
859                                 
860                                 if (temp>max) max=temp;
861                                 else if (temp<min) min=temp;
862                         }
863                         
864                         min*=-1.0;
865                         if (min>max) (*vtt)->max_value=min; else (*vtt)->max_value=max;
866
867                         if ((*vtt)->ec_enable)
868                         {
869                                 for (sample=0, mix_sample=0; sample<(*vtt)->samples_in_outputbuffer; sample++)
870                                 {                               
871                                         temp=(*vtt)->ec_output_buffer[sample];
872                                         
873                                         mix_buffer[mix_sample]+=temp*(*vtt)->ec_volume_left;
874                                         mix_sample++;
875                                         mix_buffer[mix_sample]+=temp*(*vtt)->ec_volume_right;
876                                         mix_sample++;
877                                 }
878                         }
879                         
880                         if (master_triggered)
881                         {
882                                 pthread_mutex_unlock(&render_lock);
883                                 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
884                                 {
885                                         if ((*vtt)->is_sync_client)
886                                         {
887                                                 if ((*vtt)->sync_countdown)
888                                                 {
889                                                         (*vtt)->sync_countdown--;
890                                                 }
891                                                 else
892                                                 {
893                                                         (*vtt)->sync_countdown=(*vtt)->sync_cycles;
894                                                         (*vtt)->trigger();
895                                                 }
896                                         }
897                                 }
898                                 pthread_mutex_lock(&render_lock);
899                         }
900                         
901                         vtt=render_list.begin();
902                         for (vtt++; vtt!=render_list.end(); vtt++)
903                         {
904                                 (*vtt)->render();                                       
905                                 max=(*vtt)->max_value;
906                                 min=max;
907
908                                 for (sample=0, mix_sample=0; sample<(*vtt)->samples_in_outputbuffer; sample++)
909                                 {                               
910                                         temp=(*vtt)->output_buffer[sample];
911                                         mix_buffer[mix_sample]+=temp*(*vtt)->res_volume_left;
912                                         mix_sample++;                                   
913                                         mix_buffer[mix_sample]+=temp*(*vtt)->res_volume_right;
914                                         mix_sample++;
915                                 
916                                         if (temp>max) max=temp;
917                                         else if (temp<min) min=temp;
918                                 }
919                                 
920                                 min*=-1.0;
921                                 if (min>max) (*vtt)->max_value=min; else (*vtt)->max_value=max;
922                                 
923                                 if ((*vtt)->ec_enable)
924                                 {
925                                         for (sample=0, mix_sample=0; sample<(*vtt)->samples_in_outputbuffer; sample++)
926                                         {                               
927                                                 temp=(*vtt)->ec_output_buffer[sample];
928                                                 
929                                                 mix_buffer[mix_sample]+=temp*(*vtt)->ec_volume_left;
930                                                 mix_sample++;
931                                                 mix_buffer[mix_sample]+=temp*(*vtt)->ec_volume_right;
932                                                 mix_sample++;
933                                         }
934                                 }
935                         }
936                         
937                         /* left */
938                         
939                         max=mix_max_l;
940                         min=max;
941
942                         for (sample=0; sample<samples_in_mix_buffer; sample+=2)
943                         {                               
944                                 temp=mix_buffer[sample];
945
946 #ifndef TX_DO_CLIP
947 #define FL_SHRT_MAX 32767.0
948 #define FL_SHRT_MIN -32768.0
949                                 if(temp < FL_SHRT_MIN) temp = FL_SHRT_MIN;
950                                 else if (temp > FL_SHRT_MAX) temp = FL_SHRT_MAX;
951 #endif                                  
952
953                                 mix_out_buffer[sample]=(int16_t) temp;
954                         
955                                 if (temp>max) max=temp;
956                                 else if (temp<min) min=temp;
957                         }
958                         
959                         min*=-1.0;
960                         if (min>max) mix_max_l=min; else mix_max_l=max;         
961                         
962                         /* right */
963                         
964                         max=mix_max_r;
965                         min=max;
966
967                         for (sample=1; sample<samples_in_mix_buffer; sample+=2)
968                         {                               
969                                 temp=mix_buffer[sample];
970
971 #ifndef TX_DO_CLIP
972                                 if(temp < FL_SHRT_MIN) temp = FL_SHRT_MIN;
973                                 else if (temp > FL_SHRT_MAX) temp = FL_SHRT_MAX;
974 #endif
975                                 
976                                 mix_out_buffer[sample]=(int16_t) temp;
977                         
978                                 if (temp>max) max=temp;
979                                 else if (temp<min) min=temp;
980                         }
981                         
982                         min*=-1.0;
983                         if (min>max) mix_max_r=min; else mix_max_r=max;         
984                         
985         }
986         master_triggered=0;
987                 
988         vtt=render_list.begin();
989         while (vtt!=render_list.end())
990         {
991                 next=vtt;
992                 next++;
993                 
994                 if ((*vtt)->want_stop) (*vtt)->stop_nolock();
995                 vtt=next;
996         }
997         pthread_mutex_unlock(&render_lock);
998         
999         return(mix_out_buffer);
1000 }
1001
1002 void vtt_class :: forward_all_turntables()
1003 {
1004         list <vtt_class *> :: iterator vtt, next;
1005
1006         if (render_list.size()>0)
1007         {
1008                  vtt=render_list.begin();
1009                  (*vtt)->forward_turntable();                    
1010
1011                  if (master_triggered)
1012                  {
1013                          for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
1014                          {
1015                                  if ((*vtt)->is_sync_client)
1016                                  {
1017                                          if ((*vtt)->sync_countdown)
1018                                          {
1019                                                  (*vtt)->sync_countdown--;
1020                                          }
1021                                          else
1022                                          {
1023                                                  (*vtt)->sync_countdown=(*vtt)->sync_cycles;
1024                                                  (*vtt)->trigger();
1025                                          }
1026                                  }
1027                          }
1028                  }
1029
1030                  vtt=render_list.begin();
1031                  for (vtt++; vtt!=render_list.end(); vtt++)
1032                  {
1033                          (*vtt)->forward_turntable();
1034                  }
1035                  
1036         }
1037         master_triggered=0;
1038         vtt=render_list.begin();
1039         while (vtt!=render_list.end())
1040         {
1041                 next=vtt;
1042                 next++;
1043                 
1044                 if ((*vtt)->want_stop) (*vtt)->stop_nolock();
1045                 vtt=next;
1046         }
1047 }
1048
1049
1050 int vtt_class :: trigger()
1051 {
1052         list <vtt_fx *> :: iterator effect;
1053
1054         if (!buffer) return (1);
1055         
1056         if (!is_playing) pthread_mutex_lock(&render_lock);
1057         
1058         if (res_pitch>=0) pos_f=0;
1059         else pos_f=maxpos;
1060         fade=NEED_FADE_OUT;
1061         speed=res_pitch;
1062         speed_real=res_pitch;
1063         speed_target=res_pitch;
1064         want_stop=0;
1065
1066         /* activating plugins */
1067         for (effect=fx_list.begin(); effect != fx_list.end(); effect++)
1068         {
1069                 (*effect)->activate();
1070         }
1071
1072         max_value=0;
1073         
1074         if (is_sync_master)
1075         {
1076                 master_triggered=1;
1077                 master_triggered_at=0;
1078         }
1079         
1080         if (!is_playing)
1081         {
1082                 is_playing=1;
1083         
1084                 if (is_sync_master) 
1085                 {
1086                         render_list.push_front(this);           
1087                 }               
1088                 else
1089                 {
1090                         render_list.push_back(this);
1091                 }
1092                 pthread_mutex_unlock(&render_lock);
1093         }
1094         return(0);
1095 }
1096
1097 static bool do_unlock=true;
1098
1099 int vtt_class :: stop_nolock()
1100 {
1101         list <vtt_fx *> :: iterator effect;
1102
1103         if ((!is_playing) && do_unlock) {
1104                 pthread_mutex_unlock(&render_lock);
1105                 return(1);
1106         }
1107         render_list.remove(this);
1108         want_stop=0;
1109
1110         is_playing=0;
1111         max_value=0;
1112
1113         cleanup_vtt(this);
1114         //sync_countdown=0;
1115         
1116         /* deactivating plugins */
1117         for (effect=fx_list.begin(); effect != fx_list.end(); effect++) {
1118                 (*effect)->deactivate();
1119         }
1120         
1121         return(0);
1122 }
1123
1124 int vtt_class :: stop()
1125 {
1126         int res;
1127         
1128         pthread_mutex_lock(&render_lock);
1129
1130         do_unlock=false;
1131         
1132         res=stop_nolock();
1133
1134         do_unlock=true;
1135         
1136         pthread_mutex_unlock(&render_lock);
1137
1138         return(res);
1139 }
1140
1141 void vtt_class :: set_sync_master(int master)
1142 {
1143         if (master)
1144         {
1145                 if (sync_master) sync_master->set_sync_master(0);
1146                 sync_master=this;
1147                 is_sync_master=1;
1148         }
1149         else
1150         {
1151                 if (sync_master==this) sync_master=0;
1152                 is_sync_master=0;
1153                 gui_clear_master_button(this);
1154         }
1155 }
1156
1157 void vtt_class :: set_sync_client(int slave, int cycles)
1158 {
1159         is_sync_client=slave;
1160         sync_cycles=cycles;
1161 //      sync_countdown=cycles; 
1162         sync_countdown=0;
1163 }
1164
1165 void vtt_class :: set_sync_client_ug(int slave, int cycles)
1166 {
1167         set_sync_client(slave, cycles);
1168 }
1169
1170 void vtt_class :: set_master_volume(f_prec new_volume)
1171 {
1172         list <vtt_class *> :: iterator vtt;
1173
1174         master_volume=new_volume;
1175         globals.volume=new_volume;
1176         
1177         if (main_list.size()>0)
1178         {
1179                 vol_channel_adjust=sqrt((f_prec) main_list.size());
1180                 res_master_volume=master_volume/vol_channel_adjust;             
1181         }
1182                 
1183         for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
1184         {
1185                 (*vtt)->recalc_volume();
1186         }
1187 }
1188
1189 void vtt_class :: set_master_pitch(f_prec new_pitch)
1190 {
1191         list <vtt_class *> :: iterator vtt;
1192         
1193         globals.pitch=new_pitch;
1194         for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
1195         {
1196                 (*vtt)->recalc_pitch();
1197         }
1198 }
1199
1200 void vtt_class :: enable_saturate (int newstate)
1201 {
1202         do_saturate=newstate;
1203 }
1204
1205 void vtt_class :: focus_no(int no)
1206 {
1207         list <vtt_class *> :: iterator vtt;
1208         int i;
1209
1210         for (i=0, vtt=main_list.begin(); vtt!=main_list.end(); vtt++, i++)
1211         {
1212                 if (i==no)
1213                 {
1214                         focused_vtt=(*vtt);
1215                 }
1216         }
1217 }
1218
1219 void vtt_class :: focus_next()
1220 {
1221         list <vtt_class *> :: iterator vtt;
1222         
1223         if (!focused_vtt)
1224         {
1225                 if (main_list.size())
1226                 {
1227                         focused_vtt=(*main_list.begin());
1228                 }
1229                 return;
1230         }
1231         
1232         for (vtt=main_list.begin(); vtt!=main_list.end() ; vtt++) {
1233                 if ((*vtt)==focused_vtt) {
1234                         /* Ok, we found ourselves.. */
1235                         
1236                         vtt++;
1237                         while ((vtt!=main_list.end()) && ((*vtt)->audio_hidden) ) {
1238                                 vtt++;
1239                         }
1240                         
1241                         if (vtt==main_list.end()) {
1242                                 /* No other "focusable" after this vtt so we're looking for the next */
1243                                 
1244                                 for (vtt=main_list.begin(); vtt!=main_list.end() ; vtt++) {
1245                                         if (! (*vtt)->audio_hidden) {
1246                                                 focused_vtt=(*vtt);
1247                                                 return;
1248                                         }
1249                                 }
1250                                 /* When we get here there's no "focusable" vtt at all... damn */
1251                                 focused_vtt=NULL;
1252                                 return;
1253                         } else {
1254                                 focused_vtt=(*vtt);
1255                                 return;
1256                         }
1257                 }
1258         }
1259         
1260         focused_vtt=(*main_list.begin());
1261 }
1262
1263 void vtt_class :: set_scratch(int newstate)
1264 {
1265         if (newstate)
1266         {
1267                 sp_spin.receive_input_value(0);
1268                 do_scratch=1;
1269                 sense_cycles=globals.sense_cycles;
1270         }
1271         else
1272         {
1273                 sp_spin.receive_input_value(1);
1274                 do_scratch=0;
1275         }
1276 }
1277
1278
1279 void vtt_class :: unfocus()
1280 {
1281         focused_vtt=NULL;
1282 }
1283
1284 void vtt_class :: set_x_input_parameter(tX_seqpar *sp)
1285 {
1286         x_par = sp;
1287 }
1288
1289 void vtt_class :: set_y_input_parameter(tX_seqpar *sp)
1290 {
1291         y_par = sp;
1292 }
1293
1294 void vtt_class :: xy_input(f_prec x_value, f_prec y_value)
1295 {
1296         if (x_par) x_par->handle_mouse_input(x_value*globals.mouse_speed);
1297         if (y_par) y_par->handle_mouse_input(y_value*globals.mouse_speed);
1298 }
1299
1300 #define store(data); if (fwrite((void *) &data, sizeof(data), 1, output)!=1) res+=1;
1301
1302 int  vtt_class :: save(FILE *rc, gzFile rz, char *indent) {
1303         list <vtt_fx *> :: iterator effect;
1304         char tmp_xml_buffer[4096];
1305         
1306         int res=0;
1307
1308         tX_store("%s<turntable>\n", indent);
1309         strcat(indent, "\t");
1310         
1311         store_string("name", name);
1312         if (buffer) {
1313                 store_string("audiofile", filename);
1314         } else {
1315                 store_string("audiofile", "");
1316         }
1317         store_bool("sync_master", is_sync_master);
1318         store_bool("autotrigger", autotrigger);
1319         store_bool_sp("loop", loop, sp_loop);
1320
1321         store_bool_sp("sync_client", is_sync_client, sp_sync_client);
1322         store_int_sp("sync_cycles", sync_cycles, sp_sync_cycles);
1323
1324         store_float_sp("volume", rel_volume, sp_volume);
1325         store_float_sp("pitch", rel_pitch, sp_pitch);   
1326         store_bool_sp("mute", mute, sp_mute);
1327         store_float_sp("pan", pan, sp_pan);
1328         
1329         store_bool_sp("lowpass_enable", lp_enable, sp_lp_enable);
1330         store_float_sp("lowpass_gain", lp_gain, sp_lp_gain);
1331         store_float_sp("lowpass_reso", lp_reso, sp_lp_reso);
1332         store_float_sp("lowpass_freq", lp_freq, sp_lp_freq);
1333
1334         store_bool_sp("echo_enable", ec_enable, sp_ec_enable);
1335         store_float_sp("echo_length", ec_length, sp_ec_length);
1336         store_float_sp("echo_feedback", ec_feedback, sp_ec_feedback);
1337         store_float_sp("echo_pan", ec_pan, sp_ec_pan);
1338         store_float_sp("echo_volume", ec_volume, sp_ec_volume);
1339         
1340         store_id("speed", sp_speed.get_persistence_id());
1341         store_id("trigger", sp_trigger.get_persistence_id());
1342         store_id("spin", sp_spin.get_persistence_id());
1343
1344         
1345         if (x_par) {
1346                 store_int("x_axis_mapping", x_par->get_persistence_id());
1347         }
1348         
1349         if (y_par) {
1350                 store_int("y_axis_mapping", y_par->get_persistence_id());
1351         }
1352
1353         store_bool("audio_panel_hidden", audio_hidden);
1354         store_bool("control_panel_hidden", control_hidden);
1355         store_bool("main_panel_hidden", gui.main_panel->is_hidden());
1356         store_bool("trigger_panel_hidden", gui.trigger_panel->is_hidden());
1357         store_bool("lowpass_panel_hidden", gui.lp_panel->is_hidden());
1358         store_bool("echo_panel_hidden", gui.ec_panel->is_hidden());
1359         
1360         store_bool("mix_mute", mix_mute);
1361         store_bool("mix_solo", mix_solo);
1362
1363         store_float("audio_x_zoom", gui_get_audio_x_zoom(this));
1364         
1365         tX_store("%s<fx>\n", indent);
1366         strcat(indent, "\t");
1367         
1368         for (effect=fx_list.begin(); effect!=fx_list.end(); effect++) {
1369                 (*effect)->save(rc, rz, indent);
1370         }
1371         indent[strlen(indent)-1]=0;
1372         tX_store("%s</fx>\n", indent);
1373         
1374         indent[strlen(indent)-1]=0;
1375         tX_store("%s</turntable>\n", indent);
1376         
1377         return(res);
1378 }
1379
1380 #define TX_XML_SETFILE_VERSION "1.0"
1381
1382 int  vtt_class :: save_all(FILE* rc, gzFile rz) {
1383         int res=0;
1384         list <vtt_class *> :: iterator vtt;
1385         char indent[256];
1386         
1387         tX_seqpar :: create_persistence_ids();
1388
1389         tX_store("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n");
1390         tX_store("<terminatorXset version=\"%s\">\n", TX_XML_SETFILE_VERSION);
1391         
1392         strcpy(indent, "\t");
1393
1394         //store_int(vtt_amount); obsolete
1395
1396         store_float_sp("master_volume", master_volume, sp_master_volume);
1397         store_float_sp("master_pitch", globals.pitch, sp_master_pitch);
1398
1399         for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++) {
1400                 res+=(*vtt)->save(rc, rz, indent);
1401         }
1402         
1403         sequencer.save(rc, rz, indent);
1404         
1405         tX_store("</terminatorXset>\n");
1406         
1407         return(res);
1408 }
1409
1410 int vtt_class :: load(xmlDocPtr doc, xmlNodePtr node) {
1411         char buffer[1024];
1412         bool hidden;
1413         int xpar_id=-1;
1414         int ypar_id=-1;
1415         int elementFound;
1416         char *pid_attr;
1417         int pid;
1418         double dvalue;
1419         double tmp;
1420         char tmp_xml_buffer[4096];
1421         
1422         for (xmlNodePtr cur=node->xmlChildrenNode; cur != NULL; cur = cur->next) {
1423                 if (cur->type == XML_ELEMENT_NODE) {
1424                         elementFound=0;
1425                         
1426                         restore_string_ac("name", buffer, set_name(buffer));
1427                         restore_string("audiofile", filename);
1428                         restore_bool("sync_master", is_sync_master);
1429                         restore_bool("autotrigger", autotrigger);
1430                         restore_bool_id("loop", loop, sp_loop, nop);
1431                         restore_bool_id("sync_client", is_sync_client, sp_sync_client, set_sync_client(is_sync_client, sync_cycles));
1432                         restore_int_id("sync_cycles", sync_cycles, sp_sync_cycles, set_sync_client(is_sync_client, sync_cycles));
1433                         restore_float_id("volume", rel_volume, sp_volume, recalc_volume());
1434                         restore_float_id("pitch", rel_pitch, sp_pitch, recalc_pitch());
1435                         restore_bool_id("mute", mute, sp_mute, set_mute(mute));
1436                         restore_float_id("pan", pan, sp_pan, set_pan(pan));
1437         
1438                         restore_bool_id("lowpass_enable", lp_enable, sp_lp_enable, lp_set_enable(lp_enable));
1439                         restore_float_id("lowpass_gain", lp_gain, sp_lp_gain, lp_set_gain(lp_gain)); 
1440                         restore_float_id("lowpass_reso", lp_reso, sp_lp_reso, lp_set_reso(lp_reso));
1441                         restore_float_id("lowpass_freq", lp_freq, sp_lp_freq, lp_set_freq(lp_freq));
1442         
1443                         restore_bool_id("echo_enable", ec_enable, sp_ec_enable, ec_set_enable(ec_enable));      
1444                         restore_float_id("echo_length", ec_length, sp_ec_length, ec_set_length(ec_length));
1445                         restore_float_id("echo_feedback", ec_feedback, sp_ec_feedback, ec_set_feedback(ec_feedback));
1446                         restore_float_id("echo_pan", ec_pan, sp_ec_pan, ec_set_pan(ec_pan));
1447                         restore_float_id("echo_volume", ec_volume, sp_ec_volume, ec_set_volume(ec_volume));             
1448                 
1449                         restore_id("speed", sp_speed);  
1450                         restore_id("trigger", sp_trigger);
1451                         restore_id("spin", sp_spin);
1452         
1453                         restore_int("x_axis_mapping", xpar_id);
1454                         restore_int("y_axis_mapping", ypar_id);
1455                         
1456                         restore_bool("mix_mute", mix_mute);
1457                         restore_bool("mix_solo", mix_solo);
1458         
1459                         restore_bool("audio_panel_hidden", audio_hidden);
1460                         restore_bool("control_panel_hidden", control_hidden);
1461                         restore_bool_ac("main_panel_hidden", hidden, gui.main_panel->hide(hidden));
1462                         restore_bool_ac("trigger_panel_hidden", hidden, gui.trigger_panel->hide(hidden));
1463                         restore_bool_ac("lowpass_panel_hidden", hidden, gui.lp_panel->hide(hidden));                    
1464                         restore_bool_ac("echo_panel_hidden", hidden, gui.ec_panel->hide(hidden));
1465                         restore_float_ac("audio_x_zoom", tmp, gui_set_audio_x_zoom(this,tmp));
1466                         vg_adjust_zoom(gui.zoom, this);
1467                         
1468                         if (xmlStrcmp(cur->name, (xmlChar *) "fx")==0) {
1469                                 xmlNodePtr fx=cur;
1470                                 elementFound=1;
1471                                 
1472                                 for (xmlNodePtr cur=fx->xmlChildrenNode; cur != NULL; cur = cur->next) {
1473                                         if (cur->type == XML_ELEMENT_NODE) {
1474                                                 int elementFound=0;
1475                                                 
1476                                                 if (xmlStrcmp(cur->name, (xmlChar *) "cutoff")==0) {
1477                                                         for (unsigned int t=0; t<fx_list.size(); t++) effect_down(lp_fx);
1478                                                         elementFound=1;
1479                                                 } else if (xmlStrcmp(cur->name, (xmlChar *) "lowpass")==0) {
1480                                                         for (unsigned int t=0; t<fx_list.size(); t++) effect_down(ec_fx);
1481                                                         elementFound=1;                                                         
1482                                                 } else if (xmlStrcmp(cur->name, (xmlChar *) "ladspa_plugin")==0) {
1483                                                         xmlNodePtr pluginNode=cur;
1484                                                         int ladspa_id=-1;
1485                                                         elementFound=1;
1486                                                         
1487                                                         for (xmlNodePtr cur=pluginNode->xmlChildrenNode; cur!=NULL; cur = cur->next) {
1488                                                                 int elementFound;
1489                                                                 if (cur->type == XML_ELEMENT_NODE) {
1490                                                                         elementFound=0;
1491
1492                                                                         restore_int("ladspa_id", ladspa_id);
1493                                                                         if (elementFound) break;
1494                                                                 }
1495                                                         }
1496                                                         
1497                                                         if (ladspa_id!=-1) {
1498                                                                 LADSPA_Plugin *plugin=LADSPA_Plugin::getPluginByUniqueID(ladspa_id);
1499                                                                 if (plugin) {
1500                                                                         vtt_fx_ladspa *ladspa_effect=add_effect(plugin);
1501                                                                         ladspa_effect->load(doc, pluginNode);
1502                                                                 } else {
1503                                                                         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);
1504                                                                         tx_note(buffer, true);                                                  
1505                                                                 }
1506                                                         } else {
1507                                                                 tX_warning("ladspa_plugin section without a ladspa_id element.");
1508                                                         }
1509                                                         
1510                                                 } else {
1511                                                         tX_warning("unhandled element %s in fx section.", cur->name);
1512                                                 }
1513                                         }
1514                                 }
1515                         }
1516                         
1517                         if(!elementFound) {
1518                                 tX_warning("unhandled element %s in turntable secion.", cur->name);
1519                         }
1520                 }
1521         }
1522
1523         recalc_volume();
1524
1525         if (xpar_id>=0) {
1526                 set_x_input_parameter(tX_seqpar :: get_sp_by_persistence_id(xpar_id));
1527         }
1528         else set_x_input_parameter(NULL);
1529         
1530         if (ypar_id) {
1531                 set_y_input_parameter(tX_seqpar :: get_sp_by_persistence_id(ypar_id));
1532         }
1533         else set_y_input_parameter(NULL);
1534         
1535         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gui.mute), mix_mute);
1536         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gui.solo), mix_solo);
1537         
1538         return 0;
1539 }
1540
1541 void vtt_class :: delete_all()
1542 {
1543         while (main_list.size()) {
1544                 delete((*main_list.begin()));
1545         }
1546         
1547         /* Take care of the master events.. */
1548         sequencer.delete_all_events(tX_sequencer::DELETE_ALL);
1549         
1550         /* Now reset master settings ot the default: */
1551         set_master_pitch(1.0);
1552         set_master_volume(1.0);
1553         
1554         sp_master_pitch.do_exec(1.0);
1555         sp_master_pitch.do_update_graphics();
1556
1557         sp_master_volume.do_exec(1.0);
1558         sp_master_volume.do_update_graphics();
1559         
1560         seq_update();
1561 }
1562
1563
1564 int vtt_class :: load_all(xmlDocPtr doc, char *fname) {
1565         xmlNodePtr root=xmlDocGetRootElement(doc);
1566         int elementFound=0;
1567         char fn_buff[4096];
1568         double dvalue;
1569         int res=0;
1570         int restmp=0;
1571         
1572         if (!root) {
1573                 tX_error("no root element? What kind of XML document is this?");
1574                 return 1;
1575         }
1576         
1577         if (xmlStrcmp(root->name, (const xmlChar *) "terminatorXset")) {
1578                 tX_error("this is not a terminatorXset file.")
1579                 return 2;
1580         }
1581         
1582         if (xmlGetProp(root,(xmlChar *) "version")==NULL) {
1583                 tX_error("the set file lacks a version attribute.");
1584                 return 3;
1585         }
1586         
1587         if (xmlStrcmp(xmlGetProp(root, (xmlChar *) "version"), (xmlChar *) TX_XML_SETFILE_VERSION)) {
1588                 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);
1589         }
1590         
1591         /* delete current tables... */
1592         delete_all();
1593
1594         int table_ctr=0;
1595         
1596         /* counting turntables.. */
1597         for (xmlNodePtr cur=root->xmlChildrenNode; cur != NULL; cur = cur->next) {
1598                 if (cur->type == XML_ELEMENT_NODE) {    
1599                         if (xmlStrcmp(cur->name, (xmlChar *) "turntable")==0) {
1600                                 table_ctr++;
1601                         }
1602                 }
1603         }
1604
1605         tX_debug("Found %i turntables in set.",  table_ctr);
1606
1607         ld_create_loaddlg(TX_LOADDLG_MODE_MULTI, table_ctr);
1608         ld_set_setname(fname);
1609
1610         /* parsing all */
1611         for (xmlNodePtr cur=root->xmlChildrenNode; cur != NULL; cur = cur->next) {
1612                 if (cur->type == XML_ELEMENT_NODE) {                    
1613                         elementFound=0;
1614                 
1615                         restore_float_id("master_volume", master_volume, sp_master_volume, set_master_volume(master_volume));
1616                         restore_float_id("master_pitch", globals.pitch, sp_master_pitch, set_master_pitch(globals.pitch));
1617                         
1618                         if ((!elementFound) && (xmlStrcmp(cur->name, (xmlChar *) "turntable")==0)) {
1619                                 elementFound=1;
1620                                 vtt_class *vtt=new vtt_class(1);
1621                                 vtt->load(doc, cur);
1622                                 
1623                                 tX_debug("loading a turntable..");
1624
1625                                 if (strlen(vtt->filename)) {
1626                                         strcpy(fn_buff, vtt->filename);
1627                                         ld_set_filename(fn_buff);
1628                                 
1629                                         restmp=(int) vtt->load_file(fn_buff);
1630                                         res+=restmp;
1631                                 }
1632         
1633                                 gtk_box_pack_start(GTK_BOX(control_parent), vtt->gui.control_box, TRUE, TRUE, 0);
1634                                 gtk_box_pack_start(GTK_BOX(audio_parent), vtt->gui.audio_box, TRUE, TRUE, 0);
1635                                 if (vtt->audio_hidden) vtt->hide_audio(vtt->audio_hidden);
1636                                 if (vtt->control_hidden) vtt->hide_control(vtt->control_hidden);\r
1637                         }
1638                         if ((!elementFound) && (xmlStrcmp(cur->name, (xmlChar *) "sequencer")==0)) {
1639                                 elementFound=1;
1640                                 sequencer.load(doc, cur);
1641                         }
1642                         if (!elementFound) {
1643                                 tX_warning("unhandled element %s in setfile %s", cur->name, fname);
1644                         }
1645                 }
1646         }
1647         
1648         ld_destroy();
1649         
1650         return(res);
1651 }
1652
1653 void add_vtt(GtkWidget *ctrl, GtkWidget *audio, char *fn)
1654 {
1655         vtt_class *hmmpg;
1656         hmmpg = new vtt_class(1);
1657         gtk_box_pack_start(GTK_BOX(ctrl), hmmpg->gui.control_box, TRUE, TRUE, 0);
1658         gtk_box_pack_start(GTK_BOX(audio), hmmpg->gui.audio_box, TRUE, TRUE, 0);
1659         if (fn) hmmpg->load_file(fn);
1660 }
1661
1662 extern void vg_move_fx_panel_up(GtkWidget *wid, vtt_class *vtt);
1663 extern void vg_move_fx_panel_down(GtkWidget *wid, vtt_class *vtt);
1664
1665 //#define debug_fx_stack(); for (i=fx_list.begin(); i != fx_list.end(); i++) puts((*i)->get_info_string());
1666 #define debug_fx_stack();
1667
1668 void vtt_class :: effect_up(vtt_fx *effect)
1669 {
1670         list <vtt_fx *> :: iterator i;
1671         list <vtt_fx *> :: iterator previous;
1672         int ok=0;
1673         
1674         debug_fx_stack();
1675         
1676         if ((*fx_list.begin())==effect) return;
1677         
1678         for (previous=i=fx_list.begin(); i != fx_list.end(); i++)
1679         {
1680                 if ((*i) == effect)
1681                 {
1682                         ok=1;
1683                         break;
1684                 }
1685                 previous=i;
1686         }
1687         
1688         if (ok)
1689         {       
1690                 pthread_mutex_lock(&render_lock);
1691                 fx_list.remove(effect);
1692                 fx_list.insert(previous, effect);
1693                 pthread_mutex_unlock(&render_lock);
1694
1695                 vg_move_fx_panel_up(effect->get_panel_widget(), this);
1696         }
1697         
1698         debug_fx_stack();
1699 }
1700
1701 void vtt_class :: effect_down(vtt_fx *effect)
1702 {
1703         list <vtt_fx *> :: iterator i;
1704         int ok=0;
1705
1706         debug_fx_stack();
1707                 
1708         for (i=fx_list.begin(); i != fx_list.end(); i++)
1709         {
1710                 if ((*i) == effect)
1711                 {
1712                         ok=1;
1713                         break;
1714                 }
1715         }
1716         
1717         if ((ok) && (i!=fx_list.end()))
1718         {
1719                 i++;
1720                 if (i==fx_list.end()) return;
1721                 i++;
1722
1723                 pthread_mutex_lock(&render_lock);
1724                 fx_list.remove(effect);
1725                 
1726                 fx_list.insert(i, effect);
1727                 vg_move_fx_panel_down(effect->get_panel_widget(), this);
1728                 pthread_mutex_unlock(&render_lock);
1729         }
1730         
1731 debug_fx_stack();       
1732 }
1733
1734 void vtt_class ::  effect_remove(vtt_fx_ladspa *effect)
1735 {
1736         pthread_mutex_lock(&render_lock);
1737         fx_list.remove(effect);
1738         pthread_mutex_unlock(&render_lock);
1739         
1740         delete effect;
1741 }
1742
1743 extern void gui_hide_control_panel(vtt_class *vtt, bool hide);
1744 extern void gui_hide_audio_panel(vtt_class *vtt, bool hide);
1745
1746 void vtt_class :: hide_audio(bool hide) {
1747         audio_hidden=hide;
1748         gui_hide_audio_panel(this, hide);
1749 }
1750
1751 void vtt_class :: hide_control(bool hide) {
1752         control_hidden=hide;
1753         gui_hide_control_panel(this, hide);     
1754 }
1755
1756 void vtt_class :: set_sample_rate(int samplerate) {
1757         list <vtt_class *> :: iterator vtt;
1758         double sr=(double) samplerate;
1759
1760         last_sample_rate=samplerate;
1761         
1762         for (vtt=main_list.begin(); vtt!=main_list.end() ; vtt++) {
1763                 if ((*vtt)->audiofile) {
1764                         double file_rate=(*vtt)->audiofile->get_sample_rate();
1765                         (*vtt)->audiofile_pitch_correction=file_rate/sr;
1766                 } else {
1767                         (*vtt)->audiofile_pitch_correction=1.0;
1768                 }
1769                 (*vtt)->recalc_pitch();
1770         }
1771         
1772         int no_samples=(int) (sr*0.001); // Forcing 1 ms blocksize
1773         
1774         set_mix_buffer_size(no_samples);        
1775 }
1776
1777 void vtt_class :: adjust_to_master_pitch(int master_cycles, int cycles, bool create_event) {
1778         if (!sync_master) return;
1779         if (this==sync_master) return;
1780         if (!sync_master->audiofile) return;
1781         if (!audiofile) return;
1782         
1783         double master_time=((double) master_cycles)/sync_master->rel_pitch*sync_master->audiofile->get_no_samples()/((double) sync_master->audiofile->get_sample_rate());
1784         double my_rel_pitch=((audiofile->get_no_samples()/((double) audiofile->get_sample_rate()))*((double) cycles))/master_time;
1785         
1786         if (create_event) {
1787                 sp_pitch.do_exec(my_rel_pitch);
1788                 sp_pitch.record_value(my_rel_pitch);
1789         } else {
1790                 sp_pitch.do_exec(my_rel_pitch);
1791         }
1792         
1793         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());
1794         
1795         sp_pitch.update_graphics();
1796 }