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