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