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