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