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