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