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