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