Alex: Added the new sources for terminatorX 3.5
[terminatorX.git] / src / tX_vtt.cc
1 /*
2     terminatorX - realtime audio scratching software
3     Copyright (C) 1999  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    
27 #include "tX_vtt.h"
28 #include "tX_global.h"
29 #include <stdio.h>
30 #include "malloc.h"
31 #include <math.h>
32 #include "tX_wavfunc.h"
33 #ifdef HAVE_CONFIG_H
34 #include <config.h>
35 #endif
36
37 #ifdef USE_3DNOW
38 #include "3dnow.h"
39 #endif
40
41 extern void build_vtt_gui(vtt_class *);
42 extern void gui_set_name(vtt_class *vtt, char *newname);
43 extern void gui_set_filename(vtt_class *vtt, char *newname);
44 extern void delete_gui(vtt_class *vtt);
45 extern void gui_update_display(vtt_class *vtt);
46 extern void gui_clear_master_button(vtt_class *vtt);
47 extern void cleanup_vtt(vtt_class *vtt);
48
49 int vtt_class::vtt_amount=0;
50 list <vtt_class *> vtt_class::main_list;
51 list <vtt_class *> vtt_class::render_list;
52 int16_t* vtt_class::mix_out_buffer=NULL;
53 f_prec * vtt_class::mix_buffer=NULL;
54 int vtt_class::samples_in_mix_buffer=0;
55 pthread_mutex_t vtt_class::render_lock=PTHREAD_MUTEX_INITIALIZER;
56 pthread_mutex_t vtt_class::main_lock=PTHREAD_MUTEX_INITIALIZER;
57 f_prec vtt_class::master_volume=1.0;
58 f_prec vtt_class::res_master_volume=1.0;
59 //f_prec vtt_class::saturate_fac=((f_prec) SAMPLE_MAX-SAMPLE_BORDER)*1.0/FLT_MAX;
60 f_prec vtt_class::saturate_fac=0.1;
61 int vtt_class::do_saturate=0;
62 vtt_class * vtt_class::sync_master=NULL;
63 int vtt_class::master_triggered=0;
64 int vtt_class::master_triggered_at=0;
65 vtt_class * vtt_class::focused_vtt=NULL;
66 f_prec vtt_class::mix_max=0;
67 f_prec vtt_class::vol_channel_adjust=1.0;
68
69 #define GAIN_AUTO_ADJUST 0.8
70
71 vtt_class :: vtt_class (int do_create_gui)
72 {
73         vtt_amount++;
74         sprintf (name, "Turntable %i", vtt_amount);
75         strcpy(filename, "NONE");
76         buffer=NULL;
77         samples_in_buffer=0;
78         
79         set_volume(1);
80         set_pitch(1);
81         
82         autotrigger=1;
83         loop=1;
84         
85         is_playing=0;
86         is_sync_master=0;
87         is_sync_client=0;
88         sync_cycles=0,
89         sync_countdown=0;
90         
91         x_control=CONTROL_SCRATCH;
92         y_control=CONTROL_CUTOFF;
93         
94         lp_enable=0;
95         lp_reso=0.8;
96         lp_freq=0.3;
97         lp_gain=1;
98         lp_setup(lp_gain, lp_reso, lp_freq);
99         
100         ec_enable=0;
101         ec_length=0.5;
102         ec_feedback=0.3;
103         ec_clear_buffer();
104         ec_set_length(0.5);
105         
106 //      pthread_mutex_lock(&main_lock);
107         main_list.push_back(this);
108 //      pthread_mutex_unlock(&main_lock);
109         
110         if (do_create_gui)
111         {       
112                 build_vtt_gui(this);
113         }
114         else have_gui=0;
115                 
116         set_master_volume(globals.volume);
117         set_output_buffer_size(samples_in_mix_buffer);
118 }
119
120 vtt_class :: ~vtt_class()
121 {
122         stop();
123 //      pthread_mutex_lock(&main_lock);
124         main_list.remove(this);
125 //      pthread_mutex_unlock(&main_lock);
126         if (buffer) free(buffer);
127         if (output_buffer) free(output_buffer);
128         
129         delete_gui(this);
130         vtt_amount--;
131 }
132
133 void vtt_class :: set_name(char *newname)
134 {
135         strcpy(name, newname);
136         gui_set_name(this, name);       
137 }
138
139 void vtt_class :: set_file_data(char *newfilename, int16_t *newbuffer, int samples)
140 {
141         if (is_playing) stop();
142         
143         if (buffer) free(buffer);
144         buffer=newbuffer;
145         samples_in_buffer=samples;
146         maxpos=samples;
147         
148         strcpy(filename, newfilename);
149         if (have_gui)
150         {
151                 gui_set_filename(this, newfilename);
152                 gui_update_display(this);
153         }
154         ec_set_length(ec_length);
155 }
156
157 int vtt_class :: set_output_buffer_size(int newsize)
158 {
159         if (output_buffer) free(output_buffer);
160         output_buffer = (float *) malloc (sizeof(float)*newsize);
161         end_of_outputbuffer = output_buffer + newsize; //size_t(sizeof(float)*(newsize));
162         
163         samples_in_outputbuffer=newsize;
164         inv_samples_in_outputbuffer=1.0/samples_in_outputbuffer;
165         
166         if (output_buffer) return(0);   
167         else return(0);
168 }
169
170 void vtt_class :: set_volume(f_prec newvol)
171 {
172         rel_volume=newvol;
173         res_volume=rel_volume*res_master_volume;
174 }
175
176 void vtt_class :: recalc_volume()
177 {
178         res_volume=rel_volume*res_master_volume;
179 }
180
181 void vtt_class :: set_pitch(f_prec newpitch)
182 {
183         rel_pitch=newpitch;
184 //      res_pitch=fabs(globals.pitch)*rel_pitch;
185         res_pitch=globals.pitch*rel_pitch;
186         speed=res_pitch;
187         ec_set_length(ec_length);
188 }
189
190 void vtt_class :: recalc_pitch()
191 {
192 //      res_pitch=fabs(globals.pitch)*rel_pitch;
193         res_pitch=globals.pitch*rel_pitch;
194         speed=res_pitch;
195         ec_set_length(ec_length);
196 }
197
198 void vtt_class :: set_autotrigger(int newstate)
199 {
200         autotrigger=newstate;
201 }
202
203 void vtt_class :: set_loop(int newstate)
204 {
205         loop=newstate;
206 }
207
208 void vtt_class :: set_controls (int x, int y)
209 {
210         x_control=x;
211         y_control=y;
212 }
213
214 void vtt_class :: set_mute(int newstate)
215 {
216         mute=newstate;
217 }
218
219 void vtt_class :: lp_set_enable (int newstate)
220 {
221         lp_enable=newstate;
222 }
223
224 void vtt_class :: lp_set_gain (f_prec gain)
225 {
226         lp_gain=gain;
227         lp_resgain=lp_gain*lp_autogain;
228 }
229
230 void vtt_class :: lp_set_reso(f_prec reso)
231 {
232         lp_reso=reso;
233         
234         lp_b=reso*(1.0+(1.0/lp_a));
235         lp_autogain=1.0-reso*GAIN_AUTO_ADJUST;
236         lp_resgain=lp_gain*lp_autogain;
237 }
238
239 void vtt_class :: lp_set_freq(f_prec freq)
240 {
241         lp_freq=freq;
242         
243         lp_a=1.0-freq;
244         lp_b=lp_reso*(1.0+(1.0/lp_a));
245 }
246
247 void vtt_class :: lp_setup(f_prec gain, f_prec reso, f_prec freq)
248 {
249         lp_freq=freq;
250         lp_reso=reso;
251         
252         lp_a=1.0-freq;
253         lp_b=reso*(1.0+(1.0/lp_a));
254         
255         lp_autogain=1.0-reso*GAIN_AUTO_ADJUST;
256         lp_resgain=lp_gain*lp_autogain;
257 }
258
259 void vtt_class :: ec_set_enable(int newstate)
260 {
261         ec_enable=newstate;
262 }
263
264 void vtt_class :: ec_set_length(f_prec length)
265 {
266         int delay;
267         
268         ec_length=length;
269         if (res_pitch==0) 
270         {
271                 ec_res_length=length*samples_in_buffer;
272         }
273         else
274         {
275                 ec_res_length=length*samples_in_buffer/res_pitch;       
276         }
277         
278         if (ec_res_length<0) ec_res_length*=-1;
279 //      printf("le: %f\n", ec_res_length);      
280         
281         if (ec_res_length>=EC_MAX_BUFFER) ec_res_length=EC_MAX_BUFFER;
282         
283         delay=(int )floor(ec_res_length);
284         delay-=2;
285         ec_delay=&ec_buffer[delay];
286 }
287
288 void vtt_class :: ec_set_feedback(f_prec feedback)
289 {
290         ec_feedback=feedback;
291 }
292
293 void vtt_class :: ec_clear_buffer()
294 {
295         int i;
296         
297         for (i=0; i<EC_MAX_BUFFER; i++)
298         {
299                 ec_buffer[i]=0.0;
300         }
301         ec_ptr=ec_buffer;
302 }
303
304 void vtt_class :: render()
305 {
306         if (do_scratch)
307         {
308                 if (sense_cycles>0)
309                 {
310                         sense_cycles--;
311                         if (sense_cycles==0) speed=0;
312                 }
313         }
314         render_scratch();
315         if (lp_enable) render_lp();
316         if (ec_enable) render_ec();
317 }
318
319 f_prec speed_step_last=0;
320 f_prec temp;
321
322 void vtt_class :: render_scratch()
323 {
324         int16_t *ptr;
325         
326         int sample;
327         int fade_in=0;
328         int fade_out=0;
329         int do_mute=0;
330         
331         f_prec next_speed;
332         f_prec pos_a_f;
333 //      unsigned int pos_a_i;
334         
335         f_prec amount_a;
336         f_prec amount_b;
337
338         f_prec sample_a;
339         f_prec sample_b;
340         
341         f_prec sample_res;
342         
343         f_prec *out;
344         f_prec fade_vol;        
345         
346 //      if (speed != speed_last) printf("%s: from %f to %f.\n", name, speed, speed_last);
347         
348         if (speed != speed_target)
349         {
350                 speed_target=speed;
351                 speed_step=speed_target-speed_real;
352                 speed_step/=10.0;
353         }
354                         
355         if (speed_target != speed_real)
356         {
357                 speed_real+=speed_step;
358                 if ((speed_step<0) && (speed_real<speed_target)) speed_real=speed_target;
359                 else
360                 if ((speed_step>0) && (speed_real>speed_target)) speed_real=speed_target;                       
361         }
362
363
364 /*      if (speed_real != speed_step_last)
365         {
366                 printf("last: %f now: %f \n", speed_step_last, speed_real);
367                 speed_step_last=speed_real;
368         }*/
369         
370         speed_step_last=pos_f;
371         
372         if (fade)
373         {
374                 if ((speed_last==0) && (speed_real !=0))
375                 {
376                         fade_in=1;
377                         fade=NEED_FADE_OUT;
378                 }
379         }
380         else
381         {
382                 if ((speed_last!=0) && (speed_real==0))
383                 {
384                         fade_out=1;
385                         fade=NEED_FADE_IN;
386                 }
387         }
388
389         if (mute != mute_old)
390         {
391                 if (mute)
392                 {
393                         fade_out=1; fade_in=0;
394                         fade=NEED_FADE_IN;
395                 }
396                 else
397                 {
398                         fade_in=1; fade_out=0;
399                         fade=NEED_FADE_OUT;
400                 }
401                 mute_old=mute;
402         }
403         else
404         {
405                 if (mute) do_mute=1;
406         }
407         
408         for (sample =0,out=output_buffer, fade_vol=0.0; sample < samples_in_outputbuffer;sample++, out++, fade_vol+=inv_samples_in_outputbuffer)
409         {
410                 if ((speed_real!=0) || (fade_out))
411                 {
412                         pos_f+=speed_real;
413
414                         if (pos_f>maxpos)
415                         {
416                                 pos_f-=maxpos;
417                                 if (res_pitch>0)
418                                 {
419                                         if (loop)
420                                         {
421                                         if (is_sync_master)
422                                         {
423                                                 master_triggered=1;
424                                                 master_triggered_at=sample;
425                                         }
426                                         }
427                                         else
428                                         {
429                                                 want_stop=1;
430                                         }
431                                         
432                                 }
433                         }
434                         else if (pos_f<0)
435                         {
436                                 pos_f+=maxpos;
437                                 if (res_pitch<0)
438                                 {
439                                         if (loop)
440                                         {
441                                         if (is_sync_master)
442                                         {
443                                                 master_triggered=1;
444                                                 master_triggered_at=sample;
445                                         }
446                                         }
447                                         else
448                                         {
449                                                 want_stop=1;
450                                         }
451                                 }
452                         }
453                                 
454                         pos_a_f=floor(pos_f);
455                         pos_i=(unsigned int) pos_a_f;
456                                                                 
457                         amount_b=pos_f-pos_a_f;                         
458                         amount_a=1.0-amount_b;                          
459                                 
460                         if (do_mute)
461                         {
462                                 *out=0.0;
463                         }
464                         else
465                         {
466                                 ptr=&buffer[pos_i];
467                                 sample_a=(f_prec) *ptr;
468                         
469                                 if (pos_i == samples_in_buffer) 
470                                 {
471                                         sample_b=*buffer;
472                                 }
473                                 else
474                                 {
475                                         ptr++;
476                                         sample_b=(f_prec) *ptr;
477                                 }
478                                 
479                                 sample_res=(sample_a*amount_a)+(sample_b*amount_b);
480                                                                 
481                                 if (fade_in)
482                                 {
483                                         sample_res*=fade_vol;
484                                 }
485                                 else
486                                 if (fade_out)
487                                 {
488                                         sample_res*=1.0-fade_vol;
489                                 }
490  
491                                 *out=sample_res;
492                         }
493                 }
494                 else
495                 {
496                                 *out=0;
497                 }
498         }
499         speed_last = speed_real;
500 }       
501
502 /*
503         The following lowpass filter is based on some sample code by
504         Paul Kellett <paul.kellett@maxim.abel.co.uk>
505 */
506
507 void vtt_class :: render_lp()
508 {
509 #ifdef NOT_NOT_NOT_USE_3DNOW
510         mmx_t *sample;
511         f_prec in;
512         int i;
513         mmx_t mmx_gain;
514         
515         mmx_gain.s[0]=lp_resgain;
516         mmx_gain.s[1]=lp_resgain;
517         
518         for (sample = (mmx_t *) output_buffer, sample<(mmx_t*) end_of_outputbuffer; sample++)
519         {
520                 movq_m2r(*sample, mm0);
521                 movq_m2r(mmx_gain, mm1);
522                 
523                 pfmul_r2r(mm1, mm0);
524                 
525                 
526                 lp_buf0 = lp_a * lp_buf0 + lp_freq * (in + lp_b * (lp_buf0 - lp_buf1));
527                 lp_buf1 = lp_a * lp_buf1 + lp_freq * lp_buf0;
528                 
529                 *sample=lp_buf1;
530         }
531 #else
532         f_prec *sample;
533                 
534         for (sample = output_buffer; sample<end_of_outputbuffer; sample++)
535         {
536                 lp_buf0 = lp_a * lp_buf0 + lp_freq * ((*sample)*lp_resgain + lp_b * (lp_buf0 - lp_buf1));
537                 lp_buf1 = lp_a * lp_buf1 + lp_freq * lp_buf0;
538                 
539                 *sample=lp_buf1;
540         }
541 #endif
542 }
543
544 void vtt_class :: render_ec()
545 {
546 #ifdef USE_3DNOW
547         mmx_t *sample;
548         mmx_t feed;
549
550         feed.s[0]=ec_feedback;
551         feed.s[1]=ec_feedback;
552         
553         movq_m2r(feed, mm0);
554         
555         for (sample = (mmx_t*) output_buffer; sample<(mmx_t*) end_of_outputbuffer; sample++, ec_ptr+=2)
556         {
557         
558                 if (ec_ptr>ec_delay) ec_ptr=ec_buffer;
559                 
560                 movq_m2r(*sample, mm1);
561                 movq_m2r(*ec_ptr, mm2);
562                 
563                 pfmul_r2r(mm0, mm2);
564                 pfadd_r2r(mm1, mm2);
565                 
566                 movq_r2m(mm2, *sample);
567                 movq_r2m(mm2, *ec_ptr); 
568         }       
569         
570         femms();
571 #else
572         f_prec *sample;
573         f_prec temp;
574         int i;
575
576
577         for (i=0, sample = output_buffer; i<samples_in_outputbuffer; i++, sample++, ec_ptr++)
578         {
579                 if (ec_ptr>ec_delay) ec_ptr=ec_buffer;
580                 
581                 temp= *sample + (*ec_ptr) *ec_feedback;
582                 *sample=temp;
583                 *ec_ptr=temp;
584         }       
585 #endif
586 }
587
588 int vtt_class :: set_mix_buffer_size(int no_samples)
589 {
590         list <vtt_class *> :: iterator vtt;
591         int res=0;
592         
593         if (mix_buffer) free(mix_buffer);
594         mix_buffer=(float *) malloc (sizeof(float)*no_samples);
595         if (mix_out_buffer) free(mix_out_buffer);
596         mix_out_buffer=(int16_t *) malloc (sizeof(int16_t)*no_samples);
597         samples_in_mix_buffer=no_samples;
598         
599         for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
600         {
601                 res|=(*vtt)->set_output_buffer_size(no_samples);
602         }
603         
604         if ((!mix_buffer) || (!mix_out_buffer) || res) return(1);
605         return(0);
606 }
607
608 int16_t * vtt_class :: render_all_turntables()
609 {
610         list <vtt_class *> :: iterator vtt, next;
611         int sample;
612         f_prec temp;
613 #ifdef USE_FLASH
614         f_prec max;
615         f_prec min;
616 #endif  
617         
618         pthread_mutex_lock(&render_lock);
619         
620         switch (render_list.size())
621         {
622                 case 0: for (sample=0; sample<samples_in_mix_buffer; sample++)
623                         {
624                                 mix_out_buffer[sample]=0;
625                         }
626                         break;
627 /*              case 1: vtt=render_list.begin();
628                         (*vtt)->render();
629                         
630                         if (do_saturate)
631                         for (sample=0; sample<samples_in_mix_buffer; sample++)
632                         {
633                                 temp=((*vtt)->output_buffer[sample]*(*vtt)->res_volume);
634                                 if (temp>SAMPLE_BORDER)
635                                 {
636                                         temp*=saturate_fac;
637                                         temp+=SAMPLE_BORDER;
638                                 }
639                                 else
640                                 {
641                                         if (temp<-SAMPLE_BORDER)
642                                         {
643                                                 temp*=saturate_fac;
644                                                 temp-=SAMPLE_BORDER;
645                                         }
646                                 }
647                                 mix_out_buffer[sample]=(int16_t) temp;
648                         }
649                         else
650                         for (sample=0; sample<samples_in_mix_buffer; sample++)
651                         {
652                                 mix_out_buffer[sample]=(int16_t) ((*vtt)->output_buffer[sample]*(*vtt)->res_volume);
653                         }
654                         break;*/
655                 default:
656                         vtt=render_list.begin();
657                         (*vtt)->render();                       
658 #ifdef USE_FLASH
659                         max=(*vtt)->max_value;
660                         min=max;
661                         
662                         for (sample=0; sample<samples_in_mix_buffer; sample++)
663                         {                               
664                                 temp=(*vtt)->output_buffer[sample];
665                                 mix_buffer[sample]=temp*(*vtt)->res_volume;
666                                 
667                                 if (temp>max) max=temp;
668                                 else if (temp<min) min=temp;
669                         }
670                         
671                         min*=-1.0;
672                         if (min>max) (*vtt)->max_value=min; else (*vtt)->max_value=max;
673
674 #else           
675                         for (sample=0; sample<samples_in_mix_buffer; sample++)
676                         {                               
677                                 mix_buffer[sample]=(*vtt)->output_buffer[sample]*(*vtt)->res_volume;
678                         }
679 #endif                  
680                         if (master_triggered)
681                         {
682                                 pthread_mutex_unlock(&render_lock);
683 //                              pthread_mutex_lock(&main_lock);
684                                 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
685                                 {
686                                         if ((*vtt)->is_sync_client)
687                                         {
688                                                 if ((*vtt)->sync_countdown)
689                                                 {
690                                                         (*vtt)->sync_countdown--;
691                                                 }
692                                                 else
693                                                 {
694                                                         (*vtt)->sync_countdown=(*vtt)->sync_cycles;
695                                                         (*vtt)->trigger();
696                                                 }
697                                         }
698                                 }
699 //                              pthread_mutex_unlock(&main_lock);
700                                 pthread_mutex_lock(&render_lock);
701                         }
702                         vtt=render_list.begin();
703                         for (vtt++; vtt!=render_list.end(); vtt++)
704                         {
705                                 (*vtt)->render();                                       
706 #ifdef USE_FLASH
707                                 max=(*vtt)->max_value;
708                                 min=max;
709                                 
710                                 for (sample=0; sample<samples_in_mix_buffer; sample++)
711                                 {                               
712                                         temp=(*vtt)->output_buffer[sample];
713                                         mix_buffer[sample]+=temp*(*vtt)->res_volume;
714                                 
715                                         if (temp>max) max=temp;
716                                         else if (temp<min) min=temp;
717                                 }
718                                 
719                                 min*=-1.0;
720                                 if (min>max) (*vtt)->max_value=min; else (*vtt)->max_value=max;
721 #else                           
722                                 for (sample=0; sample<samples_in_mix_buffer; sample++)
723                                 {
724                                         mix_buffer[sample]+=(*vtt)->output_buffer[sample]*(*vtt)->res_volume;
725                                 }
726 #endif                          
727                         }
728                         
729                         if (do_saturate)
730                         for (sample=0; sample<samples_in_mix_buffer; sample++)
731                         {
732                                 temp=(int16_t)mix_buffer[sample];
733                                 if (temp>SAMPLE_BORDER)
734                                 {
735                                         printf("sat: %f -> ", temp);
736                                         temp=SAMPLE_BORDER+(saturate_fac*(temp-SAMPLE_BORDER));
737                                         printf("%hi\n", int16_t(temp));                                                                 
738                                 }
739                                 else
740                                 {
741                                         if (temp<-SAMPLE_BORDER)
742                                         {
743                                                 printf("sat: %f -> ", temp);
744                                                 temp=-SAMPLE_BORDER+(saturate_fac*(temp+ SAMPLE_BORDER));
745                                         }
746                                 }
747                                 mix_out_buffer[sample]=(int16_t) temp;
748                         }
749                         else
750                         {
751 #ifdef  USE_FLASH               
752                                 max=mix_max;
753                                 for (sample=0; sample<samples_in_mix_buffer; sample++)
754                                 {                               
755                                         temp=mix_buffer[sample];
756                                         mix_out_buffer[sample]=(int16_t) temp;
757                                 
758                                         if (temp>max) max=temp;
759                                         else if (temp<min) min=temp;
760                                 }
761                                 min*=-1.0;
762                                 if (min>max) mix_max=min; else mix_max=max;
763 #else
764                                 for (sample=0; sample<samples_in_mix_buffer; sample++)
765                                 {
766                                         mix_out_buffer[sample]=(int16_t)mix_buffer[sample];
767                                 }
768 #endif                          
769                         }
770                 
771         }
772         master_triggered=0;
773                 
774         vtt=render_list.begin();
775         while (vtt!=render_list.end())
776         {
777                 next=vtt;
778                 next++;
779                 
780                 if ((*vtt)->want_stop) (*vtt)->stop_nolock();
781                 vtt=next;
782         }
783         pthread_mutex_unlock(&render_lock);
784         
785         return(mix_out_buffer);
786 }
787
788 int vtt_class :: trigger()
789 {
790         if (!buffer) return (1);
791
792         if (!is_playing) pthread_mutex_lock(&render_lock);
793         
794         if (res_pitch>=0) pos_f=0;
795         else pos_f=maxpos;
796         fade=NEED_FADE_OUT;
797         speed=res_pitch;
798         speed_real=res_pitch;
799         speed_target=res_pitch;
800 /*      mute=0;
801         mute_old=0;*/
802         want_stop=0;
803
804 #ifdef USE_FLASH
805         max_value=0;
806 #endif
807         
808         if (is_sync_master)
809         {
810                 master_triggered=1;
811                 master_triggered_at=0;
812         }
813         
814         if (!is_playing)
815         {
816                 is_playing=1;
817         
818                 if (is_sync_master) 
819                 {
820                         render_list.push_front(this);           
821                 }               
822                 else
823                 {
824                         render_list.push_back(this);
825                 }
826                 pthread_mutex_unlock(&render_lock);
827         }
828         return(0);
829 }
830
831 int vtt_class :: stop_nolock()
832 {
833 //      pthread_mutex_lock(&render_lock);
834
835         if (!is_playing) 
836         {
837                 pthread_mutex_unlock(&render_lock);
838                 return(1);
839         }
840         render_list.remove(this);
841         want_stop=0;
842
843         is_playing=0;
844 //      pthread_mutex_unlock(&render_lock);
845
846 #ifdef USE_FLASH
847         max_value=0;
848 #endif
849         cleanup_vtt(this);
850         sync_countdown=0;
851         
852         return(0);
853 }
854
855 int vtt_class :: stop()
856 {
857         int res;
858         
859         pthread_mutex_lock(&render_lock);
860
861         res=stop_nolock();
862
863         pthread_mutex_unlock(&render_lock);
864
865         return(res);
866 }
867
868 void vtt_class :: set_sync_master(int master)
869 {
870         if (master)
871         {
872                 if (sync_master) sync_master->set_sync_master(0);
873                 sync_master=this;
874                 is_sync_master=1;
875         }
876         else
877         {
878                 if (sync_master==this) sync_master=0;
879                 is_sync_master=0;
880                 gui_clear_master_button(this);
881         }
882 }
883
884 void vtt_class :: set_sync_client(int slave, int cycles)
885 {
886         is_sync_client=slave;
887         sync_cycles=cycles;
888 //      sync_countdown=cycles; 
889         sync_countdown=0;
890 }
891
892 void vtt_class :: set_master_volume(f_prec new_volume)
893 {
894         list <vtt_class *> :: iterator vtt;
895
896         master_volume=new_volume;
897         globals.volume=new_volume;
898         
899         if (main_list.size()>0)
900         {
901 //              res_master_volume=master_volume/((f_prec) main_list.size());
902                 vol_channel_adjust=sqrt((f_prec) main_list.size());
903                 res_master_volume=master_volume/vol_channel_adjust;
904                 
905         }
906                 
907         for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
908         {
909                 (*vtt)->recalc_volume();
910         }
911 }
912
913 void vtt_class :: set_master_pitch(f_prec new_pitch)
914 {
915         list <vtt_class *> :: iterator vtt;
916         
917         globals.pitch=new_pitch;
918         for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
919         {
920                 (*vtt)->recalc_pitch();
921         }
922 }
923
924 int vtt_class :: enable_saturate (int newstate)
925 {
926         do_saturate=newstate;
927 }
928
929 void vtt_class :: focus_no(int no)
930 {
931         list <vtt_class *> :: iterator vtt;
932         int i;
933
934         for (i=0, vtt=main_list.begin(); vtt!=main_list.end(); vtt++, i++)
935         {
936                 if (i==no)
937                 {
938                         focused_vtt=(*vtt);
939                 }
940         }
941 }
942
943 void vtt_class :: focus_next()
944 {
945         list <vtt_class *> :: iterator vtt;
946         
947         if (!focused_vtt)
948         {
949                 if (main_list.size())
950                 {
951                         focused_vtt=(*main_list.begin());
952                 }
953                 return;
954         }
955         
956         for (vtt=main_list.begin(); vtt!=main_list.end() ; vtt++)
957         {
958                 if ((*vtt)==focused_vtt)
959                 {
960                         vtt++;
961                         if (vtt==main_list.end())
962                         {                       
963                                 focused_vtt=(*main_list.begin());
964                                 return;
965                         }
966                         else
967                         {
968                                 focused_vtt=(*vtt);
969                                 return;
970                         }
971                 }
972         }
973         
974         focused_vtt=(*main_list.begin());
975 }
976
977 void vtt_class :: set_scratch(int newstate)
978 {
979         if (newstate)
980         {
981                 speed=0;
982                 do_scratch=1;
983                 sense_cycles=globals.sense_cycles;
984         }
985         else
986         {
987                 speed=res_pitch;
988                 do_scratch=0;
989         }
990 }
991
992 #define MAGIC 0.05
993
994 void vtt_class :: handle_input(int control, f_prec value)
995 {
996         f_prec temp;
997         
998         switch (control)
999         {
1000                 case CONTROL_SCRATCH:
1001                 if (do_scratch) speed=value*globals.mouse_speed;
1002                 sense_cycles=globals.sense_cycles;
1003                 break;
1004                 
1005                 case CONTROL_VOLUME:
1006                 temp=rel_volume+MAGIC*value*globals.mouse_speed;
1007                 if (temp>1.0) temp=1.0;
1008                 else if (temp<0) temp=0;
1009                 set_volume(temp);
1010                 break;
1011                 
1012                 case CONTROL_CUTOFF:
1013                 temp=lp_freq+MAGIC*value*globals.mouse_speed;
1014                 if (temp>0.99) temp=0.99;
1015                 else if (temp<0) temp=0;
1016                 lp_set_freq(temp);
1017                 break;
1018                 
1019                 case CONTROL_FEEDBACK:
1020                 temp=ec_feedback+MAGIC*value*globals.mouse_speed;
1021                 if (temp>1.0) temp=1.0;
1022                 else if (temp<0) temp=0;
1023                 ec_set_feedback(temp);
1024                 break;
1025         }
1026 }
1027
1028 void vtt_class :: unfocus()
1029 {
1030         focused_vtt=NULL;
1031 }
1032
1033 void vtt_class :: xy_input(f_prec x_value, f_prec y_value)
1034 {
1035         handle_input(x_control, x_value);
1036         handle_input(y_control, y_value);
1037 }
1038
1039
1040 #define store(data); if (fwrite((void *) &data, sizeof(data), 1, output)!=1) res+=1;
1041
1042 int  vtt_class :: save(FILE * output)
1043 {
1044         int res=0;
1045         
1046         store(name);
1047         store(filename);
1048         store(is_sync_master);
1049         store(is_sync_client);
1050         store(sync_cycles);
1051         store(rel_volume);
1052         store(rel_pitch);
1053         
1054         store(autotrigger);
1055         store(loop);
1056         
1057         store(mute);
1058         store(x_control);
1059         store(y_control);       
1060         
1061         store(lp_enable);
1062         store(lp_gain);
1063         store(lp_reso);
1064         store(lp_freq);
1065         
1066         store(ec_enable);
1067         store(ec_length);
1068         store(ec_feedback);
1069         
1070         return(res);
1071 }
1072
1073 #define atload(data); if (fread((void *) &data, sizeof(data), 1, input)!=1) res+=1;
1074
1075 int vtt_class :: load(FILE * input)
1076 {
1077         int res=0;
1078         
1079         atload(name);
1080         atload(filename);
1081         atload(is_sync_master);
1082         atload(is_sync_client);
1083         atload(sync_cycles);
1084         atload(rel_volume);
1085         recalc_volume();
1086         atload(rel_pitch);
1087         recalc_pitch();
1088         
1089         atload(autotrigger);
1090         atload(loop);
1091         
1092         atload(mute);
1093         atload(x_control);
1094         atload(y_control);      
1095         
1096         atload(lp_enable);
1097         atload(lp_gain);
1098         atload(lp_reso);
1099         atload(lp_freq);
1100         lp_setup(lp_gain, lp_reso, lp_freq);
1101         
1102         atload(ec_enable);
1103         atload(ec_length);
1104         ec_set_length(ec_length);
1105         atload(ec_feedback);
1106         ec_set_feedback(ec_feedback);
1107         
1108         return(res);
1109 }
1110
1111 int  vtt_class :: save_all(FILE* output)
1112 {
1113         int res=0;
1114         list <vtt_class *> :: iterator vtt;
1115         
1116         store(vtt_amount);
1117         store(master_volume);
1118         store(globals.pitch);
1119         
1120
1121         for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
1122         {
1123                 res+=(*vtt)->save(output);
1124         }
1125         
1126         return(res);
1127 }
1128
1129 int  vtt_class :: load_all(FILE* input)
1130 {
1131         int res=0, restmp=0;
1132         list <vtt_class *> :: iterator vtt;
1133         unsigned int i, max, size;
1134         int16_t *newbuffer;
1135         vtt_class *newvtt;
1136         
1137         while (main_list.size())
1138         {
1139                 delete((*main_list.begin()));
1140         }
1141                 
1142         atload(max);
1143         atload(master_volume);
1144         set_master_volume(master_volume);
1145         globals.volume=master_volume;
1146         atload(globals.pitch);  
1147         set_master_pitch(globals.pitch);
1148
1149         for (i=0; i<max; i++)
1150         {
1151                 newvtt=new vtt_class(0);
1152                 res+=newvtt->load(input);
1153                 if (strlen(newvtt->filename))
1154                 {
1155                         restmp=load_wav(newvtt->filename, &newbuffer, &size);
1156                         if (!restmp) newvtt->set_file_data(newvtt->filename, newbuffer, size/sizeof(int16_t));
1157                         res+=restmp;
1158                 }
1159         }
1160         
1161         return(res);
1162 }
1163
1164 int add_vtt(GtkWidget *daddy)
1165 {
1166         vtt_class *hmmpg;
1167         hmmpg = new vtt_class(1);
1168         gtk_box_pack_start(GTK_BOX(daddy), hmmpg->gui.frame, TRUE, TRUE, 0);
1169         gtk_widget_show(hmmpg->gui.frame);
1170 }