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