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