2 terminatorX - realtime audio scratching software
3 Copyright (C) 1999-2003 Alexander König
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.
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.
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.
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>
26 08 Dec 1999 - Switched to the new audiofile class
30 #include "tX_global.h"
34 #include "tX_mastergui.h"
35 #include "tX_sequencer.h"
43 #define tX_freemem(ptr, varname, comment); fprintf(stderr, "** free() [%s] at %08x. %s.\n", varname, ptr, comment); free(ptr);
44 #define tX_malloc(ptr, varname, comment, size, type); fprintf(stderr, "**[1/2] malloc() [%s]. Size: %i. %s.\n", varname, size, comment); ptr=type malloc(size); fprintf(stderr, "**[2/2] malloc() [%s]. ptr: %08x.\n", varname, ptr);
46 #define tX_freemem(ptr, varname, comment); free(ptr);
47 #define tX_malloc(ptr, varname, comment, size, type); ptr=type malloc(size);
50 #include "tX_loaddlg.h"
52 #define USE_PREFETCH 1
55 #define my_prefetch(base, index); __asm__ __volatile__ ("prefetch index(%0)\n" : : "r" (base));
56 #define my_prefetchw(base, index); __asm__ __volatile__ ("prefetchw index(%0)\n" : : "r" (base));
58 #define my_prefetch(base, index); /* NOP */;
59 #define my_prefetchw(base, index); /* NOP */;
62 extern void build_vtt_gui(vtt_class *);
63 extern void gui_set_name(vtt_class *vtt, char *newname);
64 extern void gui_set_filename(vtt_class *vtt, char *newname);
65 extern void delete_gui(vtt_class *vtt);
66 extern void gui_update_display(vtt_class *vtt);
67 extern void gui_clear_master_button(vtt_class *vtt);
68 extern void cleanup_vtt(vtt_class *vtt);
69 extern int vg_get_current_page(vtt_class *vtt);
70 extern f_prec gui_get_audio_x_zoom(vtt_class *vtt);
71 extern void gui_set_audio_x_zoom(vtt_class *vtt, f_prec);
73 int vtt_class::last_sample_rate=44100;
74 int vtt_class::vtt_amount=0;
75 list <vtt_class *> vtt_class::main_list;
76 list <vtt_class *> vtt_class::render_list;
77 int16_t* vtt_class::mix_out_buffer=NULL;
78 f_prec * vtt_class::mix_buffer=NULL;
79 f_prec * vtt_class::mix_buffer_end=NULL;
80 int vtt_class::solo_ctr=0;
82 int vtt_class::samples_in_mix_buffer=0;
83 pthread_mutex_t vtt_class::render_lock=PTHREAD_MUTEX_INITIALIZER;
84 f_prec vtt_class::master_volume=1.0;
85 f_prec vtt_class::res_master_volume=1.0;
86 f_prec vtt_class::saturate_fac=0.1;
87 int vtt_class::do_saturate=0;
88 vtt_class * vtt_class::sync_master=NULL;
89 int vtt_class::master_triggered=0;
90 int vtt_class::master_triggered_at=0;
91 vtt_class * vtt_class::focused_vtt=NULL;
92 f_prec vtt_class::mix_max_l=0;
93 f_prec vtt_class::mix_max_r=0;
94 f_prec vtt_class::vol_channel_adjust=1.0;
95 int vtt_class::mix_buffer_size=0;
97 #define GAIN_AUTO_ADJUST 0.8
99 vtt_class :: vtt_class (int do_create_gui)
102 sprintf (name, "Turntable %i", vtt_amount);
103 strcpy(filename, "NONE");
112 audiofile_pitch_correction=1.0;
114 ec_output_buffer=NULL;
133 lp_setup(lp_gain, lp_reso, lp_freq);
144 main_list.push_back(this);
146 /* "connecting" the seq-parameters */
148 sp_speed.set_vtt((void *) this);
149 sp_volume.set_vtt((void *) this);
150 sp_pitch.set_vtt((void *) this);
151 sp_pan.set_vtt((void *) this);
152 sp_trigger.set_vtt((void *) this);
153 sp_loop.set_vtt((void *) this);
154 sp_sync_client.set_vtt((void *) this);
155 sp_sync_cycles.set_vtt((void *) this);
156 sp_lp_enable.set_vtt((void *) this);
157 sp_lp_gain.set_vtt((void *) this);
158 sp_lp_reso.set_vtt((void *) this);
159 sp_lp_freq.set_vtt((void *) this);
160 sp_ec_enable.set_vtt((void *) this);
161 sp_ec_length.set_vtt((void *) this);
162 sp_ec_pan.set_vtt((void *) this);
163 sp_ec_volume.set_vtt((void *) this);
164 sp_ec_feedback.set_vtt((void *) this);
165 sp_mute.set_vtt((void *) this);
166 sp_spin.set_vtt((void *) this);
171 lp_fx=new vtt_fx_lp();
172 lp_fx->set_vtt((void *) this);
173 fx_list.push_back(lp_fx);
175 ec_fx=new vtt_fx_ec();
176 ec_fx->set_vtt((void *) this);
177 fx_list.push_back(ec_fx);
182 lp_fx->set_panel_widget(gui.lp_panel->get_widget());
183 ec_fx->set_panel_widget(gui.ec_panel->get_widget());
188 set_master_volume(globals.volume);
189 set_output_buffer_size(samples_in_mix_buffer/2);
192 audiofile_pitch_correction=1.0;
200 control_hidden=false;
207 vtt_class :: ~vtt_class()
212 main_list.remove(this);
213 if (audiofile) delete audiofile;
214 //if (buffer) free(buffer);
215 if (output_buffer) tX_freemem(output_buffer, "output_buffer", "vtt Destructor");
218 while (fx_list.size())
220 effect=(*fx_list.begin());
221 fx_list.remove(effect);
225 if (sync_master==this) {
232 void vtt_class :: set_name(char *newname)
234 strcpy(name, newname);
235 gui_set_name(this, name);
238 tX_audio_error vtt_class :: load_file(char *fname)
241 int was_playing=is_playing;
243 if (is_playing) stop();
245 if (audiofile) delete(audiofile);
253 audiofile=new tx_audiofile();
254 res=audiofile->load(fname);
256 if (res==TX_AUDIO_SUCCESS) {
257 buffer=audiofile->get_buffer();
258 double file_rate=audiofile->get_sample_rate();
259 audiofile_pitch_correction=file_rate/((double) last_sample_rate);
261 samples_in_buffer=audiofile->get_no_samples();
262 pos_i_max=samples_in_buffer-1;
263 maxpos=audiofile->get_no_samples();
264 strcpy(filename, fname);
265 if (was_playing) trigger();
266 // printf("Successfully loaded %s, %08x, %i\n", fname, buffer, samples_in_buffer);
271 gui_update_display(this);
273 ec_set_length(ec_length);
278 int vtt_class :: set_output_buffer_size(int newsize)
280 list <vtt_fx *> :: iterator effect;
282 if (ec_output_buffer) tX_freemem(ec_output_buffer, "ec_output_buffer", "vtt set_output_buffer_size()");
283 tX_malloc(ec_output_buffer, "ec_output_buffer", "vtt set_output_buffer_size()", sizeof(float)*newsize, (float *));
285 if (output_buffer) tX_freemem(output_buffer, "output_buffer", "vtt set_output_buffer_size()");
286 tX_malloc(output_buffer, "output_buffer", "vtt set_output_buffer_size()", sizeof(float)*newsize, (float *));
288 end_of_outputbuffer = output_buffer + newsize; //size_t(sizeof(float)*(newsize));
290 samples_in_outputbuffer=newsize;
291 inv_samples_in_outputbuffer=1.0/samples_in_outputbuffer;
293 for (effect=fx_list.begin(); effect != fx_list.end(); effect++)
295 (*effect)->reconnect_buffer();
298 if (output_buffer) return(0);
302 void vtt_class :: set_volume(f_prec newvol)
308 void vtt_class :: recalc_volume()
310 res_volume=rel_volume*res_master_volume;
311 f_prec ec_res_volume=res_volume*ec_volume;
315 res_volume_left=(1.0-pan)*res_volume;
316 res_volume_right=res_volume;
320 res_volume_left=res_volume;
321 res_volume_right=(1.0+pan)*res_volume;
325 res_volume_left=res_volume_right=res_volume;
330 ec_volume_left=(1.0-ec_pan)*ec_res_volume;
331 ec_volume_right=ec_res_volume;
335 ec_volume_left=ec_res_volume;
336 ec_volume_right=(1.0+ec_pan)*ec_res_volume;
340 ec_volume_left=ec_volume_right=ec_res_volume;
342 // printf("vtt_volume: %f, %f, l: %f, r: %f\n", rel_volume, res_volume, res_volume_left, res_volume_right);
345 void vtt_class :: set_pan(f_prec newpan)
351 void vtt_class :: set_pitch(f_prec newpitch)
357 void vtt_class :: recalc_pitch()
359 res_pitch=globals.pitch*rel_pitch;
360 res_pitch*=audiofile_pitch_correction;
362 ec_set_length(ec_length);
365 void vtt_class :: set_autotrigger(int newstate)
367 autotrigger=newstate;
370 void vtt_class :: set_loop(int newstate)
375 void vtt_class :: set_mute(int newstate)
381 void vtt_class :: set_mix_mute(int newstate)
387 void vtt_class :: set_mix_solo(int newstate)
389 if (mix_solo && !newstate)
395 else if (!mix_solo && newstate)
404 list <vtt_class *> :: iterator vtt;
406 for (vtt=main_list.begin(); vtt!=main_list.end() ; vtt++)
412 void vtt_class :: lp_set_enable (int newstate)
418 void vtt_class :: lp_reset()
423 void vtt_class :: lp_set_gain (f_prec gain)
426 lp_resgain=lp_gain*lp_autogain;
429 void vtt_class :: lp_set_reso(f_prec reso)
433 lp_b=reso*(1.0+(1.0/lp_a));
434 lp_autogain=1.0-reso*GAIN_AUTO_ADJUST;
435 lp_resgain=lp_gain*lp_autogain;
438 void vtt_class :: lp_set_freq(f_prec freq)
443 lp_b=lp_reso*(1.0+(1.0/lp_a));
446 void vtt_class :: lp_setup(f_prec gain, f_prec reso, f_prec freq)
452 lp_b=reso*(1.0+(1.0/lp_a));
454 lp_autogain=1.0-reso*GAIN_AUTO_ADJUST;
455 lp_resgain=lp_gain*lp_autogain;
458 void vtt_class :: ec_set_enable(int newstate)
465 void vtt_class :: ec_set_pan(f_prec pan)
472 /* Max length is 1.0 */
474 void vtt_class :: ec_set_length(f_prec length)
481 ec_res_length=length*samples_in_buffer;
485 ec_res_length=length*samples_in_buffer/res_pitch;
488 if (ec_res_length<0) ec_res_length*=-1;
490 if (ec_res_length>=EC_MAX_BUFFER)
492 ec_res_length=EC_MAX_BUFFER*length;
495 delay=(int )floor(ec_res_length);
497 ec_delay=&ec_buffer[delay];
500 void vtt_class :: ec_set_feedback(f_prec feedback)
502 ec_feedback=feedback;
506 void vtt_class :: ec_set_volume(f_prec volume)
512 void vtt_class :: ec_clear_buffer()
516 for (ptr=ec_buffer; ptr<=ec_delay; ptr++) {
522 void vtt_class :: render()
524 list <vtt_fx *> :: iterator effect;
527 if (sense_cycles>0) {
529 if (sense_cycles==0) sp_speed.receive_input_value(0);
534 for (effect=fx_list.begin(); effect != fx_list.end(); effect++) {
535 if ((*effect)->isEnabled()) (*effect)->run();
539 extern void vg_create_fx_gui(vtt_class *vtt, vtt_fx_ladspa *effect, LADSPA_Plugin *plugin);
541 vtt_fx_ladspa * vtt_class :: add_effect (LADSPA_Plugin *plugin)
543 vtt_fx_ladspa *new_effect;
545 new_effect = new vtt_fx_ladspa (plugin, this);
546 pthread_mutex_lock(&render_lock);
547 fx_list.push_back(new_effect);
548 if (is_playing) new_effect->activate();
549 pthread_mutex_unlock(&render_lock);
550 vg_create_fx_gui(this, new_effect, plugin);
555 void vtt_class :: calc_speed()
561 if (speed != speed_target) {
563 speed_step=speed_target-speed_real;
564 speed_step/=globals.vtt_inertia;
567 if (speed_target != speed_real) {
568 speed_real+=speed_step;
569 if ((speed_step<0) && (speed_real<speed_target)) speed_real=speed_target;
570 else if ((speed_step>0) && (speed_real>speed_target)) speed_real=speed_target;
574 if ((speed_last==0) && (speed_real !=0)) {
579 if ((speed_last!=0) && (speed_real==0)) {
585 speed_last = speed_real;
587 if (res_mute != res_mute_old) {
589 fade_out=1; fade_in=0;
592 fade_in=1; fade_out=0;
595 res_mute_old=res_mute;
597 if (res_mute) do_mute=1;
601 void vtt_class :: render_scratch()
622 for (sample =0,out=output_buffer, fade_vol=0.0; sample < samples_in_outputbuffer;sample++, out++, fade_vol+=inv_samples_in_outputbuffer) {
623 if ((speed_real!=0) || (fade_out)) {
634 master_triggered_at=sample;
640 } else if (pos_f<0) {
647 master_triggered_at=sample;
655 pos_a_f=floor(pos_f);
656 pos_i=(unsigned int) pos_a_f;
658 amount_b=pos_f-pos_a_f;
659 amount_a=1.0-amount_b;
665 sample_a=(f_prec) *ptr;
667 if (pos_i == pos_i_max) {
671 sample_b=(f_prec) *ptr;
674 sample_res=(sample_a*amount_a)+(sample_b*amount_b);
677 sample_res*=fade_vol;
678 } else if (fade_out) {
679 sample_res*=1.0-fade_vol;
690 void vtt_class :: forward_turntable()
701 if ((speed_real==0) && (!fade_out)) return;
704 /* following code is problematic as adding speed_real*n is
705 different from adding speed_real n times to pos_f.
707 well it speeds things up quite a bit and double precision
708 seems to do a satisfying job.
710 #define pos_f_test to prove that.
713 pos_f_tmp=pos_f+speed_real*samples_in_outputbuffer;
715 if ((pos_f_tmp > 0) && (pos_f_tmp < maxpos)) {
724 /* now the slow way ;) */
726 for (sample =0; sample < samples_in_outputbuffer; sample++) {
733 if (is_sync_master) {
735 master_triggered_at=sample;
741 } else if (pos_f<0) {
745 if (is_sync_master) {
747 master_triggered_at=sample;
757 diff=pos_f_tmp-pos_f;
758 if (diff!=0) printf("fast: %f, slow: %f, diff: %f, tt: %s\n", pos_f_tmp, pos_f, diff, name);
764 The following lowpass filter is based on some sample code by
765 Paul Kellett <paul.kellett@maxim.abel.co.uk>
768 void vtt_class :: render_lp()
772 for (sample = output_buffer; sample<end_of_outputbuffer; sample++) {
773 lp_buf0 = lp_a * lp_buf0 + lp_freq * ((*sample)*lp_resgain + lp_b * (lp_buf0 - lp_buf1));
774 lp_buf1 = lp_a * lp_buf1 + lp_freq * lp_buf0;
780 void vtt_class :: render_ec()
786 for (i=0, sample = output_buffer, ec_sample=ec_output_buffer; i<samples_in_outputbuffer; i++, ec_sample++,sample++, ec_ptr++) {
787 if (ec_ptr>ec_delay) ec_ptr=ec_buffer;
788 *ec_sample=(*ec_ptr) *ec_feedback;
789 *ec_ptr=*sample+*ec_sample;
793 int vtt_class :: set_mix_buffer_size(int no_samples)
795 list <vtt_class *> :: iterator vtt;
798 // printf("vtt_class::set_mix_buffer_size(), mix_buffer: %12x, mix_out: %12x, samples: %i\n", mix_buffer, mix_out_buffer, no_samples);
800 if (mix_buffer) tX_freemem(mix_buffer, "mix_buffer", "vtt set_mix_buffer_size()");
801 samples_in_mix_buffer=no_samples*2;
803 tX_malloc(mix_buffer, "mix_buffer", "vtt set_mix_buffer_size()", sizeof(float)*samples_in_mix_buffer, (float *));
804 mix_buffer_end=mix_buffer+samples_in_mix_buffer;
806 // printf("mix_buffer: %12x\n", mix_buffer);
807 // printf("mix_samples: %i, out_samples: %i", samples_in_mix_buffer, no_samples);
809 if (mix_out_buffer) tX_freemem(mix_out_buffer, "mix_out_buffer", "vtt set_mix_buffer_size()");
810 tX_malloc(mix_out_buffer, "mix_out_buffer", "vtt set_mix_buffer_size()", sizeof(int16_t)*samples_in_mix_buffer + 4, (int16_t *));
812 // printf("mix_out_buffer: %12x\n", mix_out_buffer);
814 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
816 res|=(*vtt)->set_output_buffer_size(no_samples);
819 if ((!mix_buffer) || (!mix_out_buffer) || res) return(1);
821 mix_buffer_size=no_samples;
826 int16_t * vtt_class :: render_all_turntables()
828 list <vtt_class *> :: iterator vtt, next;
835 pthread_mutex_lock(&render_lock);
837 if (render_list.size()==0)
839 for (sample=0; sample<samples_in_mix_buffer; sample++)
841 mix_out_buffer[sample]=0;
846 vtt=render_list.begin();
848 max=(*vtt)->max_value;
851 for (sample=0, mix_sample=0; sample<(*vtt)->samples_in_outputbuffer; sample++)
853 temp=(*vtt)->output_buffer[sample];
854 mix_buffer[mix_sample]=temp*(*vtt)->res_volume_left;
856 mix_buffer[mix_sample]=temp*(*vtt)->res_volume_right;
859 if (temp>max) max=temp;
860 else if (temp<min) min=temp;
864 if (min>max) (*vtt)->max_value=min; else (*vtt)->max_value=max;
866 if ((*vtt)->ec_enable)
868 for (sample=0, mix_sample=0; sample<(*vtt)->samples_in_outputbuffer; sample++)
870 temp=(*vtt)->ec_output_buffer[sample];
872 mix_buffer[mix_sample]+=temp*(*vtt)->ec_volume_left;
874 mix_buffer[mix_sample]+=temp*(*vtt)->ec_volume_right;
879 if (master_triggered)
881 pthread_mutex_unlock(&render_lock);
882 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
884 if ((*vtt)->is_sync_client)
886 if ((*vtt)->sync_countdown)
888 (*vtt)->sync_countdown--;
892 (*vtt)->sync_countdown=(*vtt)->sync_cycles;
897 pthread_mutex_lock(&render_lock);
900 vtt=render_list.begin();
901 for (vtt++; vtt!=render_list.end(); vtt++)
904 max=(*vtt)->max_value;
907 for (sample=0, mix_sample=0; sample<(*vtt)->samples_in_outputbuffer; sample++)
909 temp=(*vtt)->output_buffer[sample];
910 mix_buffer[mix_sample]+=temp*(*vtt)->res_volume_left;
912 mix_buffer[mix_sample]+=temp*(*vtt)->res_volume_right;
915 if (temp>max) max=temp;
916 else if (temp<min) min=temp;
920 if (min>max) (*vtt)->max_value=min; else (*vtt)->max_value=max;
922 if ((*vtt)->ec_enable)
924 for (sample=0, mix_sample=0; sample<(*vtt)->samples_in_outputbuffer; sample++)
926 temp=(*vtt)->ec_output_buffer[sample];
928 mix_buffer[mix_sample]+=temp*(*vtt)->ec_volume_left;
930 mix_buffer[mix_sample]+=temp*(*vtt)->ec_volume_right;
941 for (sample=0; sample<samples_in_mix_buffer; sample+=2)
943 temp=mix_buffer[sample];
946 #define FL_SHRT_MAX 32767.0
947 #define FL_SHRT_MIN -32768.0
948 if(temp < FL_SHRT_MIN) temp = FL_SHRT_MIN;
949 else if (temp > FL_SHRT_MAX) temp = FL_SHRT_MAX;
952 mix_out_buffer[sample]=(int16_t) temp;
954 if (temp>max) max=temp;
955 else if (temp<min) min=temp;
959 if (min>max) mix_max_l=min; else mix_max_l=max;
966 for (sample=1; sample<samples_in_mix_buffer; sample+=2)
968 temp=mix_buffer[sample];
971 if(temp < FL_SHRT_MIN) temp = FL_SHRT_MIN;
972 else if (temp > FL_SHRT_MAX) temp = FL_SHRT_MAX;
975 mix_out_buffer[sample]=(int16_t) temp;
977 if (temp>max) max=temp;
978 else if (temp<min) min=temp;
982 if (min>max) mix_max_r=min; else mix_max_r=max;
987 vtt=render_list.begin();
988 while (vtt!=render_list.end())
993 if ((*vtt)->want_stop) (*vtt)->stop_nolock();
996 pthread_mutex_unlock(&render_lock);
998 return(mix_out_buffer);
1001 void vtt_class :: forward_all_turntables()
1003 list <vtt_class *> :: iterator vtt, next;
1005 if (render_list.size()>0)
1007 vtt=render_list.begin();
1008 (*vtt)->forward_turntable();
1010 if (master_triggered)
1012 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
1014 if ((*vtt)->is_sync_client)
1016 if ((*vtt)->sync_countdown)
1018 (*vtt)->sync_countdown--;
1022 (*vtt)->sync_countdown=(*vtt)->sync_cycles;
1029 vtt=render_list.begin();
1030 for (vtt++; vtt!=render_list.end(); vtt++)
1032 (*vtt)->forward_turntable();
1037 vtt=render_list.begin();
1038 while (vtt!=render_list.end())
1043 if ((*vtt)->want_stop) (*vtt)->stop_nolock();
1049 int vtt_class :: trigger()
1051 list <vtt_fx *> :: iterator effect;
1053 if (!buffer) return (1);
1055 if (!is_playing) pthread_mutex_lock(&render_lock);
1057 if (res_pitch>=0) pos_f=0;
1061 speed_real=res_pitch;
1062 speed_target=res_pitch;
1065 /* activating plugins */
1066 for (effect=fx_list.begin(); effect != fx_list.end(); effect++)
1068 (*effect)->activate();
1076 master_triggered_at=0;
1085 render_list.push_front(this);
1089 render_list.push_back(this);
1091 pthread_mutex_unlock(&render_lock);
1096 static bool do_unlock=true;
1098 int vtt_class :: stop_nolock()
1100 list <vtt_fx *> :: iterator effect;
1102 if ((!is_playing) && do_unlock) {
1103 pthread_mutex_unlock(&render_lock);
1106 render_list.remove(this);
1115 /* deactivating plugins */
1116 for (effect=fx_list.begin(); effect != fx_list.end(); effect++) {
1117 (*effect)->deactivate();
1123 int vtt_class :: stop()
1127 pthread_mutex_lock(&render_lock);
1135 pthread_mutex_unlock(&render_lock);
1140 void vtt_class :: set_sync_master(int master)
1144 if (sync_master) sync_master->set_sync_master(0);
1150 if (sync_master==this) sync_master=0;
1152 gui_clear_master_button(this);
1156 void vtt_class :: set_sync_client(int slave, int cycles)
1158 is_sync_client=slave;
1160 // sync_countdown=cycles;
1164 void vtt_class :: set_sync_client_ug(int slave, int cycles)
1166 set_sync_client(slave, cycles);
1169 void vtt_class :: set_master_volume(f_prec new_volume)
1171 list <vtt_class *> :: iterator vtt;
1173 master_volume=new_volume;
1174 globals.volume=new_volume;
1176 if (main_list.size()>0)
1178 vol_channel_adjust=sqrt((f_prec) main_list.size());
1179 res_master_volume=master_volume/vol_channel_adjust;
1182 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
1184 (*vtt)->recalc_volume();
1188 void vtt_class :: set_master_pitch(f_prec new_pitch)
1190 list <vtt_class *> :: iterator vtt;
1192 globals.pitch=new_pitch;
1193 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
1195 (*vtt)->recalc_pitch();
1199 void vtt_class :: enable_saturate (int newstate)
1201 do_saturate=newstate;
1204 void vtt_class :: focus_no(int no)
1206 list <vtt_class *> :: iterator vtt;
1209 for (i=0, vtt=main_list.begin(); vtt!=main_list.end(); vtt++, i++)
1218 void vtt_class :: focus_next()
1220 list <vtt_class *> :: iterator vtt;
1224 if (main_list.size())
1226 focused_vtt=(*main_list.begin());
1231 for (vtt=main_list.begin(); vtt!=main_list.end() ; vtt++) {
1232 if ((*vtt)==focused_vtt) {
1233 /* Ok, we found ourselves.. */
1236 while ((vtt!=main_list.end()) && ((*vtt)->audio_hidden) ) {
1240 if (vtt==main_list.end()) {
1241 /* No other "focusable" after this vtt so we're looking for the next */
1243 for (vtt=main_list.begin(); vtt!=main_list.end() ; vtt++) {
1244 if (! (*vtt)->audio_hidden) {
1249 /* When we get here there's no "focusable" vtt at all... damn */
1259 focused_vtt=(*main_list.begin());
1262 void vtt_class :: set_scratch(int newstate)
1266 sp_spin.receive_input_value(0);
1268 sense_cycles=globals.sense_cycles;
1272 sp_spin.receive_input_value(1);
1278 void vtt_class :: unfocus()
1283 void vtt_class :: set_x_input_parameter(tX_seqpar *sp)
1288 void vtt_class :: set_y_input_parameter(tX_seqpar *sp)
1293 void vtt_class :: xy_input(f_prec x_value, f_prec y_value)
1295 if (x_par) x_par->handle_mouse_input(x_value*globals.mouse_speed);
1296 if (y_par) y_par->handle_mouse_input(y_value*globals.mouse_speed);
1299 #define store(data); if (fwrite((void *) &data, sizeof(data), 1, output)!=1) res+=1;
1301 int vtt_class :: save(FILE *rc, gzFile rz, char *indent) {
1302 list <vtt_fx *> :: iterator effect;
1303 char tmp_xml_buffer[4096];
1307 tX_store("%s<turntable>\n", indent);
1308 strcat(indent, "\t");
1310 store_string("name", name);
1312 store_string("audiofile", filename);
1314 store_string("audiofile", "");
1316 store_bool("sync_master", is_sync_master);
1317 store_bool("autotrigger", autotrigger);
1318 store_bool_sp("loop", loop, sp_loop);
1320 store_bool_sp("sync_client", is_sync_client, sp_sync_client);
1321 store_int_sp("sync_cycles", sync_cycles, sp_sync_cycles);
1323 store_float_sp("volume", rel_volume, sp_volume);
1324 store_float_sp("pitch", rel_pitch, sp_pitch);
1325 store_bool_sp("mute", mute, sp_mute);
1326 store_float_sp("pan", pan, sp_pan);
1328 store_bool_sp("lowpass_enable", lp_enable, sp_lp_enable);
1329 store_float_sp("lowpass_gain", lp_gain, sp_lp_gain);
1330 store_float_sp("lowpass_reso", lp_reso, sp_lp_reso);
1331 store_float_sp("lowpass_freq", lp_freq, sp_lp_freq);
1333 store_bool_sp("echo_enable", ec_enable, sp_ec_enable);
1334 store_float_sp("echo_length", ec_length, sp_ec_length);
1335 store_float_sp("echo_feedback", ec_feedback, sp_ec_feedback);
1336 store_float_sp("echo_pan", ec_pan, sp_ec_pan);
1337 store_float_sp("echo_volume", ec_volume, sp_ec_volume);
1339 store_id("speed", sp_speed.get_persistence_id());
1340 store_id("trigger", sp_trigger.get_persistence_id());
1341 store_id("spin", sp_spin.get_persistence_id());
1345 store_int("x_axis_mapping", x_par->get_persistence_id());
1349 store_int("y_axis_mapping", y_par->get_persistence_id());
1352 store_bool("audio_panel_hidden", audio_hidden);
1353 store_bool("control_panel_hidden", control_hidden);
1354 store_bool("main_panel_hidden", gui.main_panel->is_hidden());
1355 store_bool("trigger_panel_hidden", gui.trigger_panel->is_hidden());
1356 store_bool("lowpass_panel_hidden", gui.lp_panel->is_hidden());
1357 store_bool("echo_panel_hidden", gui.ec_panel->is_hidden());
1359 store_bool("mix_mute", mix_mute);
1360 store_bool("mix_solo", mix_solo);
1362 store_float("audio_x_zoom", gui_get_audio_x_zoom(this));
1364 tX_store("%s<fx>\n", indent);
1365 strcat(indent, "\t");
1367 for (effect=fx_list.begin(); effect!=fx_list.end(); effect++) {
1368 (*effect)->save(rc, rz, indent);
1370 indent[strlen(indent)-1]=0;
1371 tX_store("%s</fx>\n", indent);
1373 indent[strlen(indent)-1]=0;
1374 tX_store("%s</turntable>\n", indent);
1379 #define TX_XML_SETFILE_VERSION "1.0"
1381 int vtt_class :: save_all(FILE* rc, gzFile rz) {
1383 list <vtt_class *> :: iterator vtt;
1386 tX_seqpar :: create_persistence_ids();
1388 tX_store("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n");
1389 tX_store("<terminatorXset version=\"%s\">\n", TX_XML_SETFILE_VERSION);
1391 strcpy(indent, "\t");
1393 //store_int(vtt_amount); obsolete
1395 store_float_sp("master_volume", master_volume, sp_master_volume);
1396 store_float_sp("master_pitch", globals.pitch, sp_master_pitch);
1398 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++) {
1399 res+=(*vtt)->save(rc, rz, indent);
1402 sequencer.save(rc, rz, indent);
1404 tX_store("</terminatorXset>\n");
1409 int vtt_class :: load(xmlDocPtr doc, xmlNodePtr node) {
1419 char tmp_xml_buffer[4096];
1421 for (xmlNodePtr cur=node->xmlChildrenNode; cur != NULL; cur = cur->next) {
1422 if (cur->type == XML_ELEMENT_NODE) {
1425 restore_string_ac("name", buffer, set_name(buffer));
1426 restore_string("audiofile", filename);
1427 restore_bool("sync_master", is_sync_master);
1428 restore_bool("autotrigger", autotrigger);
1429 restore_bool_id("loop", loop, sp_loop, nop);
1430 restore_bool_id("sync_client", is_sync_client, sp_sync_client, set_sync_client(is_sync_client, sync_cycles));
1431 restore_int_id("sync_cycles", sync_cycles, sp_sync_cycles, set_sync_client(is_sync_client, sync_cycles));
1432 restore_float_id("volume", rel_volume, sp_volume, recalc_volume());
1433 restore_float_id("pitch", rel_pitch, sp_pitch, recalc_pitch());
1434 restore_bool_id("mute", mute, sp_mute, set_mute(mute));
1435 restore_float_id("pan", pan, sp_pan, set_pan(pan));
1437 restore_bool_id("lowpass_enable", lp_enable, sp_lp_enable, lp_set_enable(lp_enable));
1438 restore_float_id("lowpass_gain", lp_gain, sp_lp_gain, lp_set_gain(lp_gain));
1439 restore_float_id("lowpass_reso", lp_reso, sp_lp_reso, lp_set_reso(lp_reso));
1440 restore_float_id("lowpass_freq", lp_freq, sp_lp_freq, lp_set_freq(lp_freq));
1442 restore_bool_id("echo_enable", ec_enable, sp_ec_enable, ec_set_enable(ec_enable));
1443 restore_float_id("echo_length", ec_length, sp_ec_length, ec_set_length(ec_length));
1444 restore_float_id("echo_feedback", ec_feedback, sp_ec_feedback, ec_set_feedback(ec_feedback));
1445 restore_float_id("echo_pan", ec_pan, sp_ec_pan, ec_set_pan(ec_pan));
1446 restore_float_id("echo_volume", ec_volume, sp_ec_volume, ec_set_volume(ec_volume));
1448 restore_id("speed", sp_speed);
1449 restore_id("trigger", sp_trigger);
1450 restore_id("spin", sp_spin);
1452 restore_int("x_axis_mapping", xpar_id);
1453 restore_int("y_axis_mapping", ypar_id);
1455 restore_bool("mix_mute", mix_mute);
1456 restore_bool("mix_solo", mix_solo);
1458 restore_bool("audio_panel_hidden", audio_hidden);
1459 restore_bool("control_panel_hidden", control_hidden);
1460 restore_bool_ac("main_panel_hidden", hidden, gui.main_panel->hide(hidden));
1461 restore_bool_ac("trigger_panel_hidden", hidden, gui.trigger_panel->hide(hidden));
1462 restore_bool_ac("lowpass_panel_hidden", hidden, gui.lp_panel->hide(hidden));
1463 restore_bool_ac("echo_panel_hidden", hidden, gui.ec_panel->hide(hidden));
1464 restore_float_ac("audio_x_zoom", tmp, gui_set_audio_x_zoom(this,tmp));
1465 vg_adjust_zoom(gui.zoom, this);
1467 if (xmlStrcmp(cur->name, (xmlChar *) "fx")==0) {
1471 for (xmlNodePtr cur=fx->xmlChildrenNode; cur != NULL; cur = cur->next) {
1472 if (cur->type == XML_ELEMENT_NODE) {
1475 if (xmlStrcmp(cur->name, (xmlChar *) "cutoff")==0) {
1476 for (unsigned int t=0; t<fx_list.size(); t++) effect_down(lp_fx);
1478 } else if (xmlStrcmp(cur->name, (xmlChar *) "lowpass")==0) {
1479 for (unsigned int t=0; t<fx_list.size(); t++) effect_down(ec_fx);
1481 } else if (xmlStrcmp(cur->name, (xmlChar *) "ladspa_plugin")==0) {
1482 xmlNodePtr pluginNode=cur;
1486 for (xmlNodePtr cur=pluginNode->xmlChildrenNode; cur!=NULL; cur = cur->next) {
1488 if (cur->type == XML_ELEMENT_NODE) {
1491 restore_int("ladspa_id", ladspa_id);
1492 if (elementFound) break;
1496 if (ladspa_id!=-1) {
1497 LADSPA_Plugin *plugin=LADSPA_Plugin::getPluginByUniqueID(ladspa_id);
1499 vtt_fx_ladspa *ladspa_effect=add_effect(plugin);
1500 ladspa_effect->load(doc, pluginNode);
1502 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);
1503 tx_note(buffer, true);
1506 tX_warning("ladspa_plugin section without a ladspa_id element.");
1510 tX_warning("unhandled element %s in fx section.", cur->name);
1517 tX_warning("unhandled element %s in turntable secion.", cur->name);
1525 set_x_input_parameter(tX_seqpar :: get_sp_by_persistence_id(xpar_id));
1527 else set_x_input_parameter(NULL);
1530 set_y_input_parameter(tX_seqpar :: get_sp_by_persistence_id(ypar_id));
1532 else set_y_input_parameter(NULL);
1534 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gui.mute), mix_mute);
1535 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gui.solo), mix_solo);
1540 void vtt_class :: delete_all()
1542 while (main_list.size()) {
1543 delete((*main_list.begin()));
1546 /* Take care of the master events.. */
1547 sequencer.delete_all_events(tX_sequencer::DELETE_ALL);
1549 /* Now reset master settings ot the default: */
1550 set_master_pitch(1.0);
1551 set_master_volume(1.0);
1553 sp_master_pitch.do_exec(1.0);
1554 sp_master_pitch.do_update_graphics();
1556 sp_master_volume.do_exec(1.0);
1557 sp_master_volume.do_update_graphics();
1563 int vtt_class :: load_all(xmlDocPtr doc, char *fname) {
1564 xmlNodePtr root=xmlDocGetRootElement(doc);
1572 tX_error("no root element? What kind of XML document is this?");
1576 if (xmlStrcmp(root->name, (const xmlChar *) "terminatorXset")) {
1577 tX_error("this is not a terminatorXset file.")
1581 if (xmlGetProp(root,(xmlChar *) "version")==NULL) {
1582 tX_error("the set file lacks a version attribute.");
1586 if (xmlStrcmp(xmlGetProp(root, (xmlChar *) "version"), (xmlChar *) TX_XML_SETFILE_VERSION)) {
1587 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);
1590 /* delete current tables... */
1595 /* counting turntables.. */
1596 for (xmlNodePtr cur=root->xmlChildrenNode; cur != NULL; cur = cur->next) {
1597 if (cur->type == XML_ELEMENT_NODE) {
1598 if (xmlStrcmp(cur->name, (xmlChar *) "turntable")==0) {
1604 tX_debug("Found %i turntables in set.", table_ctr);
1606 ld_create_loaddlg(TX_LOADDLG_MODE_MULTI, table_ctr);
1607 ld_set_setname(fname);
1610 for (xmlNodePtr cur=root->xmlChildrenNode; cur != NULL; cur = cur->next) {
1611 if (cur->type == XML_ELEMENT_NODE) {
1614 restore_float_id("master_volume", master_volume, sp_master_volume, set_master_volume(master_volume));
1615 restore_float_id("master_pitch", globals.pitch, sp_master_pitch, set_master_pitch(globals.pitch));
1617 if ((!elementFound) && (xmlStrcmp(cur->name, (xmlChar *) "turntable")==0)) {
1619 vtt_class *vtt=new vtt_class(1);
1620 vtt->load(doc, cur);
1622 tX_debug("loading a turntable..");
1624 if (strlen(vtt->filename)) {
1625 strcpy(fn_buff, vtt->filename);
1626 ld_set_filename(fn_buff);
1628 restmp=(int) vtt->load_file(fn_buff);
1632 gtk_box_pack_start(GTK_BOX(control_parent), vtt->gui.control_box, TRUE, TRUE, 0);
1633 gtk_box_pack_start(GTK_BOX(audio_parent), vtt->gui.audio_box, TRUE, TRUE, 0);
1634 if (vtt->audio_hidden) vtt->hide_audio(vtt->audio_hidden);
1635 if (vtt->control_hidden) vtt->hide_control(vtt->control_hidden);
\r
1637 if ((!elementFound) && (xmlStrcmp(cur->name, (xmlChar *) "sequencer")==0)) {
1639 sequencer.load(doc, cur);
1641 if (!elementFound) {
1642 tX_warning("unhandled element %s in setfile %s", cur->name, fname);
1652 void add_vtt(GtkWidget *ctrl, GtkWidget *audio, char *fn)
1655 hmmpg = new vtt_class(1);
1656 gtk_box_pack_start(GTK_BOX(ctrl), hmmpg->gui.control_box, TRUE, TRUE, 0);
1657 gtk_box_pack_start(GTK_BOX(audio), hmmpg->gui.audio_box, TRUE, TRUE, 0);
1658 if (fn) hmmpg->load_file(fn);
1661 extern void vg_move_fx_panel_up(GtkWidget *wid, vtt_class *vtt);
1662 extern void vg_move_fx_panel_down(GtkWidget *wid, vtt_class *vtt);
1664 //#define debug_fx_stack(); for (i=fx_list.begin(); i != fx_list.end(); i++) puts((*i)->get_info_string());
1665 #define debug_fx_stack();
1667 void vtt_class :: effect_up(vtt_fx *effect)
1669 list <vtt_fx *> :: iterator i;
1670 list <vtt_fx *> :: iterator previous;
1675 if ((*fx_list.begin())==effect) return;
1677 for (previous=i=fx_list.begin(); i != fx_list.end(); i++)
1689 pthread_mutex_lock(&render_lock);
1690 fx_list.remove(effect);
1691 fx_list.insert(previous, effect);
1692 pthread_mutex_unlock(&render_lock);
1694 vg_move_fx_panel_up(effect->get_panel_widget(), this);
1700 void vtt_class :: effect_down(vtt_fx *effect)
1702 list <vtt_fx *> :: iterator i;
1707 for (i=fx_list.begin(); i != fx_list.end(); i++)
1716 if ((ok) && (i!=fx_list.end()))
1719 if (i==fx_list.end()) return;
1722 pthread_mutex_lock(&render_lock);
1723 fx_list.remove(effect);
1725 fx_list.insert(i, effect);
1726 vg_move_fx_panel_down(effect->get_panel_widget(), this);
1727 pthread_mutex_unlock(&render_lock);
1733 void vtt_class :: effect_remove(vtt_fx_ladspa *effect)
1735 pthread_mutex_lock(&render_lock);
1736 fx_list.remove(effect);
1737 pthread_mutex_unlock(&render_lock);
1742 extern void gui_hide_control_panel(vtt_class *vtt, bool hide);
1743 extern void gui_hide_audio_panel(vtt_class *vtt, bool hide);
1745 void vtt_class :: hide_audio(bool hide) {
1747 gui_hide_audio_panel(this, hide);
1750 void vtt_class :: hide_control(bool hide) {
1751 control_hidden=hide;
1752 gui_hide_control_panel(this, hide);
1755 void vtt_class :: set_sample_rate(int samplerate) {
1756 list <vtt_class *> :: iterator vtt;
1757 double sr=(double) samplerate;
1759 last_sample_rate=samplerate;
1761 for (vtt=main_list.begin(); vtt!=main_list.end() ; vtt++) {
1762 if ((*vtt)->audiofile) {
1763 double file_rate=(*vtt)->audiofile->get_sample_rate();
1764 (*vtt)->audiofile_pitch_correction=file_rate/sr;
1766 (*vtt)->audiofile_pitch_correction=1.0;
1768 (*vtt)->recalc_pitch();
1771 int no_samples=(int) (sr*0.001); // Forcing 1 ms blocksize
1773 set_mix_buffer_size(no_samples);
1776 void vtt_class :: adjust_to_master_pitch(int master_cycles, int cycles, bool create_event) {
1777 if (!sync_master) return;
1778 if (this==sync_master) return;
1779 if (!sync_master->audiofile) return;
1780 if (!audiofile) return;
1782 double master_time=((double) master_cycles)/sync_master->rel_pitch*sync_master->audiofile->get_no_samples()/((double) sync_master->audiofile->get_sample_rate());
1783 double my_rel_pitch=((audiofile->get_no_samples()/((double) audiofile->get_sample_rate()))*((double) cycles))/master_time;
1786 sp_pitch.do_exec(my_rel_pitch);
1787 sp_pitch.record_value(my_rel_pitch);
1789 sp_pitch.do_exec(my_rel_pitch);
1792 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());
1794 sp_pitch.update_graphics();