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