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