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);
363 tX_debug("setting pitch: rel: %lf -> res: %lf", rel_pitch, res_pitch);
366 void vtt_class :: set_autotrigger(int newstate)
368 autotrigger=newstate;
371 void vtt_class :: set_loop(int newstate)
376 void vtt_class :: set_mute(int newstate)
382 void vtt_class :: set_mix_mute(int newstate)
388 void vtt_class :: set_mix_solo(int newstate)
390 if (mix_solo && !newstate)
396 else if (!mix_solo && newstate)
405 list <vtt_class *> :: iterator vtt;
407 for (vtt=main_list.begin(); vtt!=main_list.end() ; vtt++)
413 void vtt_class :: lp_set_enable (int newstate)
419 void vtt_class :: lp_reset()
424 void vtt_class :: lp_set_gain (f_prec gain)
427 lp_resgain=lp_gain*lp_autogain;
430 void vtt_class :: lp_set_reso(f_prec reso)
434 lp_b=reso*(1.0+(1.0/lp_a));
435 lp_autogain=1.0-reso*GAIN_AUTO_ADJUST;
436 lp_resgain=lp_gain*lp_autogain;
439 void vtt_class :: lp_set_freq(f_prec freq)
444 lp_b=lp_reso*(1.0+(1.0/lp_a));
447 void vtt_class :: lp_setup(f_prec gain, f_prec reso, f_prec freq)
453 lp_b=reso*(1.0+(1.0/lp_a));
455 lp_autogain=1.0-reso*GAIN_AUTO_ADJUST;
456 lp_resgain=lp_gain*lp_autogain;
459 void vtt_class :: ec_set_enable(int newstate)
466 void vtt_class :: ec_set_pan(f_prec pan)
473 /* Max length is 1.0 */
475 void vtt_class :: ec_set_length(f_prec length)
482 ec_res_length=length*samples_in_buffer;
486 ec_res_length=length*samples_in_buffer/res_pitch;
489 if (ec_res_length<0) ec_res_length*=-1;
491 if (ec_res_length>=EC_MAX_BUFFER)
493 ec_res_length=EC_MAX_BUFFER*length;
496 delay=(int )floor(ec_res_length);
498 ec_delay=&ec_buffer[delay];
501 void vtt_class :: ec_set_feedback(f_prec feedback)
503 ec_feedback=feedback;
507 void vtt_class :: ec_set_volume(f_prec volume)
513 void vtt_class :: ec_clear_buffer()
517 for (ptr=ec_buffer; ptr<=ec_delay; ptr++)
524 void vtt_class :: render()
526 list <vtt_fx *> :: iterator effect;
533 if (sense_cycles==0) sp_speed.receive_input_value(0);
538 for (effect=fx_list.begin(); effect != fx_list.end(); effect++)
540 if ((*effect)->isEnabled()) (*effect)->run();
544 extern void vg_create_fx_gui(vtt_class *vtt, vtt_fx_ladspa *effect, LADSPA_Plugin *plugin);
546 vtt_fx_ladspa * vtt_class :: add_effect (LADSPA_Plugin *plugin)
548 vtt_fx_ladspa *new_effect;
550 new_effect = new vtt_fx_ladspa (plugin, this);
551 pthread_mutex_lock(&render_lock);
552 fx_list.push_back(new_effect);
553 if (is_playing) new_effect->activate();
554 pthread_mutex_unlock(&render_lock);
555 vg_create_fx_gui(this, new_effect, plugin);
560 void vtt_class :: calc_speed()
566 if (speed != speed_target)
569 speed_step=speed_target-speed_real;
573 if (speed_target != speed_real)
575 speed_real+=speed_step;
576 if ((speed_step<0) && (speed_real<speed_target)) speed_real=speed_target;
578 if ((speed_step>0) && (speed_real>speed_target)) speed_real=speed_target;
583 if ((speed_last==0) && (speed_real !=0))
591 if ((speed_last!=0) && (speed_real==0))
598 speed_last = speed_real;
600 if (res_mute != res_mute_old)
604 fade_out=1; fade_in=0;
609 fade_in=1; fade_out=0;
612 res_mute_old=res_mute;
616 if (res_mute) do_mute=1;
620 void vtt_class :: render_scratch()
641 for (sample =0,out=output_buffer, fade_vol=0.0; sample < samples_in_outputbuffer;sample++, out++, fade_vol+=inv_samples_in_outputbuffer)
643 if ((speed_real!=0) || (fade_out))
658 master_triggered_at=sample;
678 master_triggered_at=sample;
688 pos_a_f=floor(pos_f);
689 pos_i=(unsigned int) pos_a_f;
691 amount_b=pos_f-pos_a_f;
692 amount_a=1.0-amount_b;
701 sample_a=(f_prec) *ptr;
703 if (pos_i == pos_i_max)
710 sample_b=(f_prec) *ptr;
713 sample_res=(sample_a*amount_a)+(sample_b*amount_b);
717 sample_res*=fade_vol;
722 sample_res*=1.0-fade_vol;
735 void vtt_class :: forward_turntable()
746 if ((speed_real==0) && (!fade_out)) return;
749 /* following code is problematic as adding speed_real*n is
750 different from adding speed_real n times to pos_f.
752 well it speeds things up quite a bit and double precision
753 seems to do a satisfying job.
755 #define pos_f_test to prove that.
758 pos_f_tmp=pos_f+speed_real*samples_in_outputbuffer;
760 if ((pos_f_tmp > 0) && (pos_f_tmp < maxpos))
770 /* now the slow way ;) */
772 for (sample =0; sample < samples_in_outputbuffer; sample++)
786 master_triggered_at=sample;
806 master_triggered_at=sample;
820 diff=pos_f_tmp-pos_f;
821 if (diff!=0) printf("fast: %f, slow: %f, diff: %f, tt: %s\n", pos_f_tmp, pos_f, diff, name);
827 The following lowpass filter is based on some sample code by
828 Paul Kellett <paul.kellett@maxim.abel.co.uk>
831 void vtt_class :: render_lp()
835 for (sample = output_buffer; sample<end_of_outputbuffer; sample++)
837 lp_buf0 = lp_a * lp_buf0 + lp_freq * ((*sample)*lp_resgain + lp_b * (lp_buf0 - lp_buf1));
838 lp_buf1 = lp_a * lp_buf1 + lp_freq * lp_buf0;
844 void vtt_class :: render_ec()
850 for (i=0, sample = output_buffer, ec_sample=ec_output_buffer; i<samples_in_outputbuffer; i++, ec_sample++,sample++, ec_ptr++)
852 if (ec_ptr>ec_delay) ec_ptr=ec_buffer;
853 *ec_sample=(*ec_ptr) *ec_feedback;
854 *ec_ptr=*sample+*ec_sample;
858 int vtt_class :: set_mix_buffer_size(int no_samples)
860 list <vtt_class *> :: iterator vtt;
863 // printf("vtt_class::set_mix_buffer_size(), mix_buffer: %12x, mix_out: %12x, samples: %i\n", mix_buffer, mix_out_buffer, no_samples);
865 if (mix_buffer) tX_freemem(mix_buffer, "mix_buffer", "vtt set_mix_buffer_size()");
866 samples_in_mix_buffer=no_samples*2;
868 tX_malloc(mix_buffer, "mix_buffer", "vtt set_mix_buffer_size()", sizeof(float)*samples_in_mix_buffer, (float *));
869 mix_buffer_end=mix_buffer+samples_in_mix_buffer;
871 // printf("mix_buffer: %12x\n", mix_buffer);
872 // printf("mix_samples: %i, out_samples: %i", samples_in_mix_buffer, no_samples);
874 if (mix_out_buffer) tX_freemem(mix_out_buffer, "mix_out_buffer", "vtt set_mix_buffer_size()");
875 tX_malloc(mix_out_buffer, "mix_out_buffer", "vtt set_mix_buffer_size()", sizeof(int16_t)*samples_in_mix_buffer + 4, (int16_t *));
877 // printf("mix_out_buffer: %12x\n", mix_out_buffer);
879 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
881 res|=(*vtt)->set_output_buffer_size(no_samples);
884 if ((!mix_buffer) || (!mix_out_buffer) || res) return(1);
886 mix_buffer_size=no_samples;
891 int16_t * vtt_class :: render_all_turntables()
893 list <vtt_class *> :: iterator vtt, next;
900 pthread_mutex_lock(&render_lock);
902 if (render_list.size()==0)
904 for (sample=0; sample<samples_in_mix_buffer; sample++)
906 mix_out_buffer[sample]=0;
911 vtt=render_list.begin();
913 max=(*vtt)->max_value;
916 for (sample=0, mix_sample=0; sample<(*vtt)->samples_in_outputbuffer; sample++)
918 temp=(*vtt)->output_buffer[sample];
919 mix_buffer[mix_sample]=temp*(*vtt)->res_volume_left;
921 mix_buffer[mix_sample]=temp*(*vtt)->res_volume_right;
924 if (temp>max) max=temp;
925 else if (temp<min) min=temp;
929 if (min>max) (*vtt)->max_value=min; else (*vtt)->max_value=max;
931 if ((*vtt)->ec_enable)
933 for (sample=0, mix_sample=0; sample<(*vtt)->samples_in_outputbuffer; sample++)
935 temp=(*vtt)->ec_output_buffer[sample];
937 mix_buffer[mix_sample]+=temp*(*vtt)->ec_volume_left;
939 mix_buffer[mix_sample]+=temp*(*vtt)->ec_volume_right;
944 if (master_triggered)
946 pthread_mutex_unlock(&render_lock);
947 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
949 if ((*vtt)->is_sync_client)
951 if ((*vtt)->sync_countdown)
953 (*vtt)->sync_countdown--;
957 (*vtt)->sync_countdown=(*vtt)->sync_cycles;
962 pthread_mutex_lock(&render_lock);
965 vtt=render_list.begin();
966 for (vtt++; vtt!=render_list.end(); vtt++)
969 max=(*vtt)->max_value;
972 for (sample=0, mix_sample=0; sample<(*vtt)->samples_in_outputbuffer; sample++)
974 temp=(*vtt)->output_buffer[sample];
975 mix_buffer[mix_sample]+=temp*(*vtt)->res_volume_left;
977 mix_buffer[mix_sample]+=temp*(*vtt)->res_volume_right;
980 if (temp>max) max=temp;
981 else if (temp<min) min=temp;
985 if (min>max) (*vtt)->max_value=min; else (*vtt)->max_value=max;
987 if ((*vtt)->ec_enable)
989 for (sample=0, mix_sample=0; sample<(*vtt)->samples_in_outputbuffer; sample++)
991 temp=(*vtt)->ec_output_buffer[sample];
993 mix_buffer[mix_sample]+=temp*(*vtt)->ec_volume_left;
995 mix_buffer[mix_sample]+=temp*(*vtt)->ec_volume_right;
1006 for (sample=0; sample<samples_in_mix_buffer; sample+=2)
1008 temp=mix_buffer[sample];
1011 #define FL_SHRT_MAX 32767.0
1012 #define FL_SHRT_MIN -32768.0
1013 if(temp < FL_SHRT_MIN) temp = FL_SHRT_MIN;
1014 else if (temp > FL_SHRT_MAX) temp = FL_SHRT_MAX;
1017 mix_out_buffer[sample]=(int16_t) temp;
1019 if (temp>max) max=temp;
1020 else if (temp<min) min=temp;
1024 if (min>max) mix_max_l=min; else mix_max_l=max;
1031 for (sample=1; sample<samples_in_mix_buffer; sample+=2)
1033 temp=mix_buffer[sample];
1036 if(temp < FL_SHRT_MIN) temp = FL_SHRT_MIN;
1037 else if (temp > FL_SHRT_MAX) temp = FL_SHRT_MAX;
1040 mix_out_buffer[sample]=(int16_t) temp;
1042 if (temp>max) max=temp;
1043 else if (temp<min) min=temp;
1047 if (min>max) mix_max_r=min; else mix_max_r=max;
1052 vtt=render_list.begin();
1053 while (vtt!=render_list.end())
1058 if ((*vtt)->want_stop) (*vtt)->stop_nolock();
1061 pthread_mutex_unlock(&render_lock);
1063 return(mix_out_buffer);
1066 void vtt_class :: forward_all_turntables()
1068 list <vtt_class *> :: iterator vtt, next;
1070 if (render_list.size()>0)
1072 vtt=render_list.begin();
1073 (*vtt)->forward_turntable();
1075 if (master_triggered)
1077 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
1079 if ((*vtt)->is_sync_client)
1081 if ((*vtt)->sync_countdown)
1083 (*vtt)->sync_countdown--;
1087 (*vtt)->sync_countdown=(*vtt)->sync_cycles;
1094 vtt=render_list.begin();
1095 for (vtt++; vtt!=render_list.end(); vtt++)
1097 (*vtt)->forward_turntable();
1102 vtt=render_list.begin();
1103 while (vtt!=render_list.end())
1108 if ((*vtt)->want_stop) (*vtt)->stop_nolock();
1114 int vtt_class :: trigger()
1116 list <vtt_fx *> :: iterator effect;
1118 if (!buffer) return (1);
1120 if (!is_playing) pthread_mutex_lock(&render_lock);
1122 if (res_pitch>=0) pos_f=0;
1126 speed_real=res_pitch;
1127 speed_target=res_pitch;
1130 /* activating plugins */
1131 for (effect=fx_list.begin(); effect != fx_list.end(); effect++)
1133 (*effect)->activate();
1141 master_triggered_at=0;
1150 render_list.push_front(this);
1154 render_list.push_back(this);
1156 pthread_mutex_unlock(&render_lock);
1161 static bool do_unlock=true;
1163 int vtt_class :: stop_nolock()
1165 list <vtt_fx *> :: iterator effect;
1167 if ((!is_playing) && do_unlock)
1169 pthread_mutex_unlock(&render_lock);
1172 render_list.remove(this);
1181 /* deactivating plugins */
1182 for (effect=fx_list.begin(); effect != fx_list.end(); effect++)
1184 (*effect)->deactivate();
1190 int vtt_class :: stop()
1194 pthread_mutex_lock(&render_lock);
1202 pthread_mutex_unlock(&render_lock);
1207 void vtt_class :: set_sync_master(int master)
1211 if (sync_master) sync_master->set_sync_master(0);
1217 if (sync_master==this) sync_master=0;
1219 gui_clear_master_button(this);
1223 void vtt_class :: set_sync_client(int slave, int cycles)
1225 is_sync_client=slave;
1227 // sync_countdown=cycles;
1231 void vtt_class :: set_sync_client_ug(int slave, int cycles)
1233 set_sync_client(slave, cycles);
1236 void vtt_class :: set_master_volume(f_prec new_volume)
1238 list <vtt_class *> :: iterator vtt;
1240 master_volume=new_volume;
1241 globals.volume=new_volume;
1243 if (main_list.size()>0)
1245 vol_channel_adjust=sqrt((f_prec) main_list.size());
1246 res_master_volume=master_volume/vol_channel_adjust;
1249 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
1251 (*vtt)->recalc_volume();
1255 void vtt_class :: set_master_pitch(f_prec new_pitch)
1257 list <vtt_class *> :: iterator vtt;
1259 globals.pitch=new_pitch;
1260 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
1262 (*vtt)->recalc_pitch();
1266 void vtt_class :: enable_saturate (int newstate)
1268 do_saturate=newstate;
1271 void vtt_class :: focus_no(int no)
1273 list <vtt_class *> :: iterator vtt;
1276 for (i=0, vtt=main_list.begin(); vtt!=main_list.end(); vtt++, i++)
1285 void vtt_class :: focus_next()
1287 list <vtt_class *> :: iterator vtt;
1291 if (main_list.size())
1293 focused_vtt=(*main_list.begin());
1298 for (vtt=main_list.begin(); vtt!=main_list.end() ; vtt++) {
1299 if ((*vtt)==focused_vtt) {
1300 /* Ok, we found ourselves.. */
1303 while ((vtt!=main_list.end()) && ((*vtt)->audio_hidden) ) {
1307 if (vtt==main_list.end()) {
1308 /* No other "focusable" after this vtt so we're looking for the next */
1310 for (vtt=main_list.begin(); vtt!=main_list.end() ; vtt++) {
1311 if (! (*vtt)->audio_hidden) {
1316 /* When we get here there's no "focusable" vtt at all... damn */
1326 focused_vtt=(*main_list.begin());
1329 void vtt_class :: set_scratch(int newstate)
1333 sp_spin.receive_input_value(0);
1335 sense_cycles=globals.sense_cycles;
1339 sp_spin.receive_input_value(1);
1345 void vtt_class :: unfocus()
1350 void vtt_class :: set_x_input_parameter(tX_seqpar *sp)
1355 void vtt_class :: set_y_input_parameter(tX_seqpar *sp)
1360 void vtt_class :: xy_input(f_prec x_value, f_prec y_value)
1362 if (x_par) x_par->handle_mouse_input(x_value*globals.mouse_speed);
1363 if (y_par) y_par->handle_mouse_input(y_value*globals.mouse_speed);
1366 #define store(data); if (fwrite((void *) &data, sizeof(data), 1, output)!=1) res+=1;
1368 int vtt_class :: save(FILE *rc, gzFile rz, char *indent) {
1369 list <vtt_fx *> :: iterator effect;
1370 char tmp_xml_buffer[4096];
1374 tX_store("%s<turntable>\n", indent);
1375 strcat(indent, "\t");
1377 store_string("name", name);
1379 store_string("audiofile", filename);
1381 store_string("audiofile", "");
1383 store_bool("sync_master", is_sync_master);
1384 store_bool("autotrigger", autotrigger);
1385 store_bool_sp("loop", loop, sp_loop);
1387 store_bool_sp("sync_client", is_sync_client, sp_sync_client);
1388 store_int_sp("sync_cycles", sync_cycles, sp_sync_cycles);
1390 store_float_sp("volume", rel_volume, sp_volume);
1391 store_float_sp("pitch", rel_pitch, sp_pitch);
1392 store_bool_sp("mute", mute, sp_mute);
1393 store_float_sp("pan", pan, sp_pan);
1395 store_bool_sp("lowpass_enable", lp_enable, sp_lp_enable);
1396 store_float_sp("lowpass_gain", lp_gain, sp_lp_gain);
1397 store_float_sp("lowpass_reso", lp_reso, sp_lp_reso);
1398 store_float_sp("lowpass_freq", lp_freq, sp_lp_freq);
1400 store_bool_sp("echo_enable", ec_enable, sp_ec_enable);
1401 store_float_sp("echo_length", ec_length, sp_ec_length);
1402 store_float_sp("echo_feedback", ec_feedback, sp_ec_feedback);
1403 store_float_sp("echo_pan", ec_pan, sp_ec_pan);
1404 store_float_sp("echo_volume", ec_volume, sp_ec_volume);
1406 store_id("speed", sp_speed.get_persistence_id());
1407 store_id("trigger", sp_trigger.get_persistence_id());
1408 store_id("spin", sp_spin.get_persistence_id());
1412 store_int("x_axis_mapping", x_par->get_persistence_id());
1416 store_int("y_axis_mapping", y_par->get_persistence_id());
1419 store_bool("audio_panel_hidden", audio_hidden);
1420 store_bool("control_panel_hidden", control_hidden);
1421 store_bool("main_panel_hidden", gui.main_panel->is_hidden());
1422 store_bool("trigger_panel_hidden", gui.trigger_panel->is_hidden());
1423 store_bool("lowpass_panel_hidden", gui.lp_panel->is_hidden());
1424 store_bool("echo_panel_hidden", gui.ec_panel->is_hidden());
1426 store_float("audio_x_zoom", gui_get_audio_x_zoom(this));
1428 tX_store("%s<fx>\n", indent);
1429 strcat(indent, "\t");
1431 for (effect=fx_list.begin(); effect!=fx_list.end(); effect++) {
1432 (*effect)->save(rc, rz, indent);
1434 indent[strlen(indent)-1]=0;
1435 tX_store("%s</fx>\n", indent);
1437 indent[strlen(indent)-1]=0;
1438 tX_store("%s</turntable>\n", indent);
1443 #define TX_XML_SETFILE_VERSION "1.0"
1445 int vtt_class :: save_all(FILE* rc, gzFile rz) {
1447 list <vtt_class *> :: iterator vtt;
1450 tX_seqpar :: create_persistence_ids();
1452 tX_store("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n");
1453 tX_store("<terminatorXset version=\"%s\">\n", TX_XML_SETFILE_VERSION);
1455 strcpy(indent, "\t");
1457 //store_int(vtt_amount); obsolete
1459 store_float_sp("master_volume", master_volume, sp_master_volume);
1460 store_float_sp("master_pitch", globals.pitch, sp_master_pitch);
1462 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++) {
1463 res+=(*vtt)->save(rc, rz, indent);
1466 sequencer.save(rc, rz, indent);
1468 tX_store("</terminatorXset>\n");
1473 int vtt_class :: load(xmlDocPtr doc, xmlNodePtr node) {
1483 char tmp_xml_buffer[4096];
1485 for (xmlNodePtr cur=node->xmlChildrenNode; cur != NULL; cur = cur->next) {
1486 if (cur->type == XML_ELEMENT_NODE) {
1489 restore_string_ac("name", buffer, set_name(buffer));
1490 restore_string("audiofile", filename);
1491 restore_bool("sync_master", is_sync_master);
1492 restore_bool("autotrigger", autotrigger);
1493 restore_bool_id("loop", loop, sp_loop, nop);
1494 restore_bool_id("sync_client", is_sync_client, sp_sync_client, set_sync_client(is_sync_client, sync_cycles));
1495 restore_int_id("sync_cycles", sync_cycles, sp_sync_cycles, set_sync_client(is_sync_client, sync_cycles));
1496 restore_float_id("volume", rel_volume, sp_volume, recalc_volume());
1497 restore_float_id("pitch", rel_pitch, sp_pitch, recalc_pitch());
1498 restore_bool_id("mute", mute, sp_mute, set_mute(mute));
1499 restore_float_id("pan", pan, sp_pan, set_pan(pan));
1501 restore_bool_id("lowpass_enable", lp_enable, sp_lp_enable, lp_set_enable(lp_enable));
1502 restore_float_id("lowpass_gain", lp_gain, sp_lp_gain, lp_set_gain(lp_gain));
1503 restore_float_id("lowpass_reso", lp_reso, sp_lp_reso, lp_set_reso(lp_reso));
1504 restore_float_id("lowpass_freq", lp_freq, sp_lp_freq, lp_set_freq(lp_freq));
1506 restore_bool_id("echo_enable", ec_enable, sp_ec_enable, ec_set_enable(ec_enable));
1507 restore_float_id("echo_length", ec_length, sp_ec_length, ec_set_length(ec_length));
1508 restore_float_id("echo_feedback", ec_feedback, sp_ec_feedback, ec_set_feedback(ec_feedback));
1509 restore_float_id("echo_pan", ec_pan, sp_ec_pan, ec_set_pan(ec_pan));
1510 restore_float_id("echo_volume", ec_volume, sp_ec_volume, ec_set_volume(ec_volume));
1512 restore_id("speed", sp_speed);
1513 restore_id("trigger", sp_trigger);
1514 restore_id("spin", sp_spin);
1516 restore_int("x_axis_mapping", xpar_id);
1517 restore_int("y_axis_mapping", ypar_id);
1519 restore_bool("audio_panel_hidden", audio_hidden);
1520 restore_bool("control_panel_hidden", control_hidden);
1521 restore_bool_ac("main_panel_hidden", hidden, gui.main_panel->hide(hidden));
1522 restore_bool_ac("trigger_panel_hidden", hidden, gui.trigger_panel->hide(hidden));
1523 restore_bool_ac("lowpass_panel_hidden", hidden, gui.lp_panel->hide(hidden));
1524 restore_bool_ac("echo_panel_hidden", hidden, gui.ec_panel->hide(hidden));
1525 restore_float_ac("audio_x_zoom", tmp, gui_set_audio_x_zoom(this,tmp));
1526 vg_adjust_zoom(gui.zoom, this);
1528 if (xmlStrcmp(cur->name, (xmlChar *) "fx")==0) {
1532 for (xmlNodePtr cur=fx->xmlChildrenNode; cur != NULL; cur = cur->next) {
1533 if (cur->type == XML_ELEMENT_NODE) {
1536 if (xmlStrcmp(cur->name, (xmlChar *) "cutoff")==0) {
1537 for (unsigned int t=0; t<fx_list.size(); t++) effect_down(lp_fx);
1539 } else if (xmlStrcmp(cur->name, (xmlChar *) "lowpass")==0) {
1540 for (unsigned int t=0; t<fx_list.size(); t++) effect_down(ec_fx);
1542 } else if (xmlStrcmp(cur->name, (xmlChar *) "ladspa_plugin")==0) {
1543 xmlNodePtr pluginNode=cur;
1547 for (xmlNodePtr cur=pluginNode->xmlChildrenNode; cur!=NULL; cur = cur->next) {
1549 if (cur->type == XML_ELEMENT_NODE) {
1552 restore_int("ladspa_id", ladspa_id);
1553 if (elementFound) break;
1557 if (ladspa_id!=-1) {
1558 LADSPA_Plugin *plugin=LADSPA_Plugin::getPluginByUniqueID(ladspa_id);
1560 vtt_fx_ladspa *ladspa_effect=add_effect(plugin);
1561 ladspa_effect->load(doc, pluginNode);
1563 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);
1564 tx_note(buffer, true);
1567 tX_warning("ladspa_plugin section without a ladspa_id element.");
1571 tX_warning("unhandled element %s in fx section.", cur->name);
1578 tX_warning("unhandled element %s in turntable secion.", cur->name);
1586 set_x_input_parameter(tX_seqpar :: get_sp_by_persistence_id(xpar_id));
1588 else set_x_input_parameter(NULL);
1591 set_y_input_parameter(tX_seqpar :: get_sp_by_persistence_id(ypar_id));
1593 else set_y_input_parameter(NULL);
1598 void vtt_class :: delete_all()
1600 while (main_list.size()) {
1601 delete((*main_list.begin()));
1606 int vtt_class :: load_all(xmlDocPtr doc, char *fname) {
1607 xmlNodePtr root=xmlDocGetRootElement(doc);
1618 tX_error("no root element? What kind of XML document is this?");
1622 if (xmlStrcmp(root->name, (const xmlChar *) "terminatorXset")) {
1623 tX_error("this is not a terminatorXset file.")
1627 if (xmlGetProp(root,(xmlChar *) "version")==NULL) {
1628 tX_error("the set file lacks a version attribute.");
1632 if (xmlStrcmp(xmlGetProp(root, (xmlChar *) "version"), (xmlChar *) TX_XML_SETFILE_VERSION)) {
1633 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);
1636 /* delete current tables... */
1641 /* counting turntables.. */
1642 for (xmlNodePtr cur=root->xmlChildrenNode; cur != NULL; cur = cur->next) {
1643 if (cur->type == XML_ELEMENT_NODE) {
1644 if (xmlStrcmp(cur->name, (xmlChar *) "turntable")==0) {
1650 tX_debug("Found %i turntables in set.", table_ctr);
1652 ld_create_loaddlg(TX_LOADDLG_MODE_MULTI, table_ctr);
1653 ld_set_setname(fname);
1656 for (xmlNodePtr cur=root->xmlChildrenNode; cur != NULL; cur = cur->next) {
1657 if (cur->type == XML_ELEMENT_NODE) {
1660 restore_float_id("master_volume", master_volume, sp_master_volume, set_master_volume(master_volume));
1661 restore_float_id("master_pitch", globals.pitch, sp_master_pitch, set_master_pitch(globals.pitch));
1663 if ((!elementFound) && (xmlStrcmp(cur->name, (xmlChar *) "turntable")==0)) {
1665 vtt_class *vtt=new vtt_class(1);
1666 vtt->load(doc, cur);
1668 tX_debug("loading a turntable..");
1670 if (strlen(vtt->filename)) {
1671 strcpy(fn_buff, vtt->filename);
1672 ld_set_filename(fn_buff);
1674 restmp=(int) vtt->load_file(fn_buff);
1678 gtk_box_pack_start(GTK_BOX(control_parent), vtt->gui.control_box, TRUE, TRUE, 0);
1679 gtk_box_pack_start(GTK_BOX(audio_parent), vtt->gui.audio_box, TRUE, TRUE, 0);
1680 if (vtt->audio_hidden) vtt->hide_audio(vtt->audio_hidden);
1681 if (vtt->control_hidden) vtt->hide_control(vtt->control_hidden);
\r
1683 if ((!elementFound) && (xmlStrcmp(cur->name, (xmlChar *) "sequencer")==0)) {
1685 sequencer.load(doc, cur);
1687 if (!elementFound) {
1688 tX_warning("unhandled element %s in setfile %s", cur->name, fname);
1698 void add_vtt(GtkWidget *ctrl, GtkWidget *audio, char *fn)
1701 hmmpg = new vtt_class(1);
1702 gtk_box_pack_start(GTK_BOX(ctrl), hmmpg->gui.control_box, TRUE, TRUE, 0);
1703 gtk_box_pack_start(GTK_BOX(audio), hmmpg->gui.audio_box, TRUE, TRUE, 0);
1704 if (fn) hmmpg->load_file(fn);
1707 extern void vg_move_fx_panel_up(GtkWidget *wid, vtt_class *vtt);
1708 extern void vg_move_fx_panel_down(GtkWidget *wid, vtt_class *vtt);
1710 //#define debug_fx_stack(); for (i=fx_list.begin(); i != fx_list.end(); i++) puts((*i)->get_info_string());
1711 #define debug_fx_stack();
1713 void vtt_class :: effect_up(vtt_fx *effect)
1715 list <vtt_fx *> :: iterator i;
1716 list <vtt_fx *> :: iterator previous;
1721 if ((*fx_list.begin())==effect) return;
1723 for (previous=i=fx_list.begin(); i != fx_list.end(); i++)
1735 pthread_mutex_lock(&render_lock);
1736 fx_list.remove(effect);
1737 fx_list.insert(previous, effect);
1738 pthread_mutex_unlock(&render_lock);
1740 vg_move_fx_panel_up(effect->get_panel_widget(), this);
1746 void vtt_class :: effect_down(vtt_fx *effect)
1748 list <vtt_fx *> :: iterator i;
1753 for (i=fx_list.begin(); i != fx_list.end(); i++)
1762 if ((ok) && (i!=fx_list.end()))
1765 if (i==fx_list.end()) return;
1768 pthread_mutex_lock(&render_lock);
1769 fx_list.remove(effect);
1771 fx_list.insert(i, effect);
1772 vg_move_fx_panel_down(effect->get_panel_widget(), this);
1773 pthread_mutex_unlock(&render_lock);
1779 void vtt_class :: effect_remove(vtt_fx_ladspa *effect)
1781 pthread_mutex_lock(&render_lock);
1782 fx_list.remove(effect);
1783 pthread_mutex_unlock(&render_lock);
1788 extern void gui_hide_control_panel(vtt_class *vtt, bool hide);
1789 extern void gui_hide_audio_panel(vtt_class *vtt, bool hide);
1791 void vtt_class :: hide_audio(bool hide) {
1793 gui_hide_audio_panel(this, hide);
1796 void vtt_class :: hide_control(bool hide) {
1797 control_hidden=hide;
1798 gui_hide_control_panel(this, hide);
1801 void vtt_class :: set_sample_rate(int samplerate) {
1802 list <vtt_class *> :: iterator vtt;
1803 double sr=(double) samplerate;
1805 last_sample_rate=samplerate;
1807 for (vtt=main_list.begin(); vtt!=main_list.end() ; vtt++) {
1808 if ((*vtt)->audiofile) {
1809 double file_rate=(*vtt)->audiofile->get_sample_rate();
1810 (*vtt)->audiofile_pitch_correction=file_rate/sr;
1812 (*vtt)->audiofile_pitch_correction=1.0;
1814 (*vtt)->recalc_pitch();
1817 int no_samples=(int) (sr*0.001); // Forcing 1 ms blocksize
1819 set_mix_buffer_size(no_samples);
1822 void vtt_class :: adjust_to_master_pitch(int master_cycles, int cycles, bool create_event) {
1823 if (!sync_master) return;
1824 if (this==sync_master) return;
1825 if (!sync_master->audiofile) return;
1826 if (!audiofile) return;
1828 double master_time=((double) master_cycles)/sync_master->rel_pitch*sync_master->audiofile->get_no_samples()/((double) sync_master->audiofile->get_sample_rate());
1829 double my_rel_pitch=((audiofile->get_no_samples()/((double) audiofile->get_sample_rate()))*((double) cycles))/master_time;
1832 sp_pitch.do_exec(my_rel_pitch);
1833 sp_pitch.record_value(my_rel_pitch);
1835 sp_pitch.do_exec(my_rel_pitch);
1838 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());
1840 sp_pitch.update_graphics();