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