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