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