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");
111 audiofile_pitch_correction=1.0;
113 ec_output_buffer=NULL;
132 lp_setup(lp_gain, lp_reso, lp_freq);
143 main_list.push_back(this);
145 /* "connecting" the seq-parameters */
147 sp_speed.set_vtt((void *) this);
148 sp_volume.set_vtt((void *) this);
149 sp_pitch.set_vtt((void *) this);
150 sp_pan.set_vtt((void *) this);
151 sp_trigger.set_vtt((void *) this);
152 sp_loop.set_vtt((void *) this);
153 sp_sync_client.set_vtt((void *) this);
154 sp_sync_cycles.set_vtt((void *) this);
155 sp_lp_enable.set_vtt((void *) this);
156 sp_lp_gain.set_vtt((void *) this);
157 sp_lp_reso.set_vtt((void *) this);
158 sp_lp_freq.set_vtt((void *) this);
159 sp_ec_enable.set_vtt((void *) this);
160 sp_ec_length.set_vtt((void *) this);
161 sp_ec_pan.set_vtt((void *) this);
162 sp_ec_volume.set_vtt((void *) this);
163 sp_ec_feedback.set_vtt((void *) this);
164 sp_mute.set_vtt((void *) this);
165 sp_spin.set_vtt((void *) this);
170 lp_fx=new vtt_fx_lp();
171 lp_fx->set_vtt((void *) this);
172 fx_list.push_back(lp_fx);
174 ec_fx=new vtt_fx_ec();
175 ec_fx->set_vtt((void *) this);
176 fx_list.push_back(ec_fx);
181 lp_fx->set_panel_widget(gui.lp_panel->get_widget());
182 ec_fx->set_panel_widget(gui.ec_panel->get_widget());
187 set_master_volume(globals.volume);
188 set_output_buffer_size(samples_in_mix_buffer/2);
191 audiofile_pitch_correction=1.0;
199 control_hidden=false;
206 vtt_class :: ~vtt_class()
211 main_list.remove(this);
212 if (audiofile) delete audiofile;
213 //if (buffer) free(buffer);
214 if (output_buffer) tX_freemem(output_buffer, "output_buffer", "vtt Destructor");
217 while (fx_list.size())
219 effect=(*fx_list.begin());
220 fx_list.remove(effect);
224 if (sync_master==this) {
231 void vtt_class :: set_name(char *newname)
233 strcpy(name, newname);
234 gui_set_name(this, name);
237 tX_audio_error vtt_class :: load_file(char *fname)
240 int was_playing=is_playing;
242 if (is_playing) stop();
244 if (audiofile) delete(audiofile);
251 audiofile=new tx_audiofile();
252 res=audiofile->load(fname);
254 if (res==TX_AUDIO_SUCCESS) {
255 buffer=audiofile->get_buffer();
256 double file_rate=audiofile->get_sample_rate();
257 audiofile_pitch_correction=file_rate/((double) last_sample_rate);
259 samples_in_buffer=audiofile->get_no_samples();
260 maxpos=audiofile->get_no_samples();
261 strcpy(filename, fname);
262 if (was_playing) trigger();
263 // printf("Successfully loaded %s, %08x, %i\n", fname, buffer, samples_in_buffer);
268 gui_update_display(this);
270 ec_set_length(ec_length);
275 int vtt_class :: set_output_buffer_size(int newsize)
277 list <vtt_fx *> :: iterator effect;
279 if (ec_output_buffer) tX_freemem(ec_output_buffer, "ec_output_buffer", "vtt set_output_buffer_size()");
280 tX_malloc(ec_output_buffer, "ec_output_buffer", "vtt set_output_buffer_size()", sizeof(float)*newsize, (float *));
282 if (output_buffer) tX_freemem(output_buffer, "output_buffer", "vtt set_output_buffer_size()");
283 tX_malloc(output_buffer, "output_buffer", "vtt set_output_buffer_size()", sizeof(float)*newsize, (float *));
285 end_of_outputbuffer = output_buffer + newsize; //size_t(sizeof(float)*(newsize));
287 samples_in_outputbuffer=newsize;
288 inv_samples_in_outputbuffer=1.0/samples_in_outputbuffer;
290 for (effect=fx_list.begin(); effect != fx_list.end(); effect++)
292 (*effect)->reconnect_buffer();
295 if (output_buffer) return(0);
299 void vtt_class :: set_volume(f_prec newvol)
305 void vtt_class :: recalc_volume()
307 res_volume=rel_volume*res_master_volume;
308 f_prec ec_res_volume=res_volume*ec_volume;
312 res_volume_left=(1.0-pan)*res_volume;
313 res_volume_right=res_volume;
317 res_volume_left=res_volume;
318 res_volume_right=(1.0+pan)*res_volume;
322 res_volume_left=res_volume_right=res_volume;
327 ec_volume_left=(1.0-ec_pan)*ec_res_volume;
328 ec_volume_right=ec_res_volume;
332 ec_volume_left=ec_res_volume;
333 ec_volume_right=(1.0+ec_pan)*ec_res_volume;
337 ec_volume_left=ec_volume_right=ec_res_volume;
339 // printf("vtt_volume: %f, %f, l: %f, r: %f\n", rel_volume, res_volume, res_volume_left, res_volume_right);
342 void vtt_class :: set_pan(f_prec newpan)
348 void vtt_class :: set_pitch(f_prec newpitch)
354 void vtt_class :: recalc_pitch()
356 res_pitch=globals.pitch*rel_pitch;
357 res_pitch*=audiofile_pitch_correction;
359 ec_set_length(ec_length);
360 tX_debug("setting pitch: rel: %lf -> res: %lf", rel_pitch, res_pitch);
363 void vtt_class :: set_autotrigger(int newstate)
365 autotrigger=newstate;
368 void vtt_class :: set_loop(int newstate)
373 void vtt_class :: set_mute(int newstate)
379 void vtt_class :: set_mix_mute(int newstate)
385 void vtt_class :: set_mix_solo(int newstate)
387 if (mix_solo && !newstate)
393 else if (!mix_solo && newstate)
402 list <vtt_class *> :: iterator vtt;
404 for (vtt=main_list.begin(); vtt!=main_list.end() ; vtt++)
410 void vtt_class :: lp_set_enable (int newstate)
416 void vtt_class :: lp_reset()
421 void vtt_class :: lp_set_gain (f_prec gain)
424 lp_resgain=lp_gain*lp_autogain;
427 void vtt_class :: lp_set_reso(f_prec reso)
431 lp_b=reso*(1.0+(1.0/lp_a));
432 lp_autogain=1.0-reso*GAIN_AUTO_ADJUST;
433 lp_resgain=lp_gain*lp_autogain;
436 void vtt_class :: lp_set_freq(f_prec freq)
441 lp_b=lp_reso*(1.0+(1.0/lp_a));
444 void vtt_class :: lp_setup(f_prec gain, f_prec reso, f_prec freq)
450 lp_b=reso*(1.0+(1.0/lp_a));
452 lp_autogain=1.0-reso*GAIN_AUTO_ADJUST;
453 lp_resgain=lp_gain*lp_autogain;
456 void vtt_class :: ec_set_enable(int newstate)
463 void vtt_class :: ec_set_pan(f_prec pan)
470 /* Max length is 1.0 */
472 void vtt_class :: ec_set_length(f_prec length)
479 ec_res_length=length*samples_in_buffer;
483 ec_res_length=length*samples_in_buffer/res_pitch;
486 if (ec_res_length<0) ec_res_length*=-1;
488 if (ec_res_length>=EC_MAX_BUFFER)
490 ec_res_length=EC_MAX_BUFFER*length;
493 delay=(int )floor(ec_res_length);
495 ec_delay=&ec_buffer[delay];
498 void vtt_class :: ec_set_feedback(f_prec feedback)
500 ec_feedback=feedback;
504 void vtt_class :: ec_set_volume(f_prec volume)
510 void vtt_class :: ec_clear_buffer()
514 for (ptr=ec_buffer; ptr<=ec_delay; ptr++)
521 void vtt_class :: render()
523 list <vtt_fx *> :: iterator effect;
530 if (sense_cycles==0) sp_speed.receive_input_value(0);
535 for (effect=fx_list.begin(); effect != fx_list.end(); effect++)
537 if ((*effect)->isEnabled()) (*effect)->run();
541 extern void vg_create_fx_gui(vtt_class *vtt, vtt_fx_ladspa *effect, LADSPA_Plugin *plugin);
543 vtt_fx_ladspa * vtt_class :: add_effect (LADSPA_Plugin *plugin)
545 vtt_fx_ladspa *new_effect;
547 new_effect = new vtt_fx_ladspa (plugin, this);
548 pthread_mutex_lock(&render_lock);
549 fx_list.push_back(new_effect);
550 if (is_playing) new_effect->activate();
551 pthread_mutex_unlock(&render_lock);
552 vg_create_fx_gui(this, new_effect, plugin);
557 void vtt_class :: calc_speed()
563 if (speed != speed_target)
566 speed_step=speed_target-speed_real;
570 if (speed_target != speed_real)
572 speed_real+=speed_step;
573 if ((speed_step<0) && (speed_real<speed_target)) speed_real=speed_target;
575 if ((speed_step>0) && (speed_real>speed_target)) speed_real=speed_target;
580 if ((speed_last==0) && (speed_real !=0))
588 if ((speed_last!=0) && (speed_real==0))
595 speed_last = speed_real;
597 if (res_mute != res_mute_old)
601 fade_out=1; fade_in=0;
606 fade_in=1; fade_out=0;
609 res_mute_old=res_mute;
613 if (res_mute) do_mute=1;
617 void vtt_class :: render_scratch()
638 for (sample =0,out=output_buffer, fade_vol=0.0; sample < samples_in_outputbuffer;sample++, out++, fade_vol+=inv_samples_in_outputbuffer)
640 if ((speed_real!=0) || (fade_out))
655 master_triggered_at=sample;
675 master_triggered_at=sample;
685 pos_a_f=floor(pos_f);
686 pos_i=(unsigned int) pos_a_f;
688 amount_b=pos_f-pos_a_f;
689 amount_a=1.0-amount_b;
698 sample_a=(f_prec) *ptr;
700 if (pos_i == samples_in_buffer)
707 sample_b=(f_prec) *ptr;
710 sample_res=(sample_a*amount_a)+(sample_b*amount_b);
714 sample_res*=fade_vol;
719 sample_res*=1.0-fade_vol;
732 void vtt_class :: forward_turntable()
743 if ((speed_real==0) && (!fade_out)) return;
746 /* following code is problematic as adding speed_real*n is
747 different from adding speed_real n times to pos_f.
749 well it speeds things up quite a bit and double precision
750 seems to do a satisfying job.
752 #define pos_f_test to prove that.
755 pos_f_tmp=pos_f+speed_real*samples_in_outputbuffer;
757 if ((pos_f_tmp > 0) && (pos_f_tmp < maxpos))
767 /* now the slow way ;) */
769 for (sample =0; sample < samples_in_outputbuffer; sample++)
783 master_triggered_at=sample;
803 master_triggered_at=sample;
817 diff=pos_f_tmp-pos_f;
818 if (diff!=0) printf("fast: %f, slow: %f, diff: %f, tt: %s\n", pos_f_tmp, pos_f, diff, name);
824 The following lowpass filter is based on some sample code by
825 Paul Kellett <paul.kellett@maxim.abel.co.uk>
828 void vtt_class :: render_lp()
832 for (sample = output_buffer; sample<end_of_outputbuffer; sample++)
834 lp_buf0 = lp_a * lp_buf0 + lp_freq * ((*sample)*lp_resgain + lp_b * (lp_buf0 - lp_buf1));
835 lp_buf1 = lp_a * lp_buf1 + lp_freq * lp_buf0;
841 void vtt_class :: render_ec()
847 for (i=0, sample = output_buffer, ec_sample=ec_output_buffer; i<samples_in_outputbuffer; i++, ec_sample++,sample++, ec_ptr++)
849 if (ec_ptr>ec_delay) ec_ptr=ec_buffer;
850 *ec_sample=(*ec_ptr) *ec_feedback;
851 *ec_ptr=*sample+*ec_sample;
855 int vtt_class :: set_mix_buffer_size(int no_samples)
857 list <vtt_class *> :: iterator vtt;
860 // printf("vtt_class::set_mix_buffer_size(), mix_buffer: %12x, mix_out: %12x, samples: %i\n", mix_buffer, mix_out_buffer, no_samples);
862 if (mix_buffer) tX_freemem(mix_buffer, "mix_buffer", "vtt set_mix_buffer_size()");
863 samples_in_mix_buffer=no_samples*2;
865 tX_malloc(mix_buffer, "mix_buffer", "vtt set_mix_buffer_size()", sizeof(float)*samples_in_mix_buffer, (float *));
866 mix_buffer_end=mix_buffer+samples_in_mix_buffer;
868 // printf("mix_buffer: %12x\n", mix_buffer);
869 // printf("mix_samples: %i, out_samples: %i", samples_in_mix_buffer, no_samples);
871 if (mix_out_buffer) tX_freemem(mix_out_buffer, "mix_out_buffer", "vtt set_mix_buffer_size()");
872 tX_malloc(mix_out_buffer, "mix_out_buffer", "vtt set_mix_buffer_size()", sizeof(int16_t)*samples_in_mix_buffer + 4, (int16_t *));
874 // printf("mix_out_buffer: %12x\n", mix_out_buffer);
876 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
878 res|=(*vtt)->set_output_buffer_size(no_samples);
881 if ((!mix_buffer) || (!mix_out_buffer) || res) return(1);
883 mix_buffer_size=no_samples;
888 int16_t * vtt_class :: render_all_turntables()
890 list <vtt_class *> :: iterator vtt, next;
897 pthread_mutex_lock(&render_lock);
899 if (render_list.size()==0)
901 for (sample=0; sample<samples_in_mix_buffer; sample++)
903 mix_out_buffer[sample]=0;
908 vtt=render_list.begin();
910 max=(*vtt)->max_value;
913 for (sample=0, mix_sample=0; sample<(*vtt)->samples_in_outputbuffer; sample++)
915 temp=(*vtt)->output_buffer[sample];
916 mix_buffer[mix_sample]=temp*(*vtt)->res_volume_left;
918 mix_buffer[mix_sample]=temp*(*vtt)->res_volume_right;
921 if (temp>max) max=temp;
922 else if (temp<min) min=temp;
926 if (min>max) (*vtt)->max_value=min; else (*vtt)->max_value=max;
928 if ((*vtt)->ec_enable)
930 for (sample=0, mix_sample=0; sample<(*vtt)->samples_in_outputbuffer; sample++)
932 temp=(*vtt)->ec_output_buffer[sample];
934 mix_buffer[mix_sample]+=temp*(*vtt)->ec_volume_left;
936 mix_buffer[mix_sample]+=temp*(*vtt)->ec_volume_right;
941 if (master_triggered)
943 pthread_mutex_unlock(&render_lock);
944 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
946 if ((*vtt)->is_sync_client)
948 if ((*vtt)->sync_countdown)
950 (*vtt)->sync_countdown--;
954 (*vtt)->sync_countdown=(*vtt)->sync_cycles;
959 pthread_mutex_lock(&render_lock);
962 vtt=render_list.begin();
963 for (vtt++; vtt!=render_list.end(); vtt++)
966 max=(*vtt)->max_value;
969 for (sample=0, mix_sample=0; sample<(*vtt)->samples_in_outputbuffer; sample++)
971 temp=(*vtt)->output_buffer[sample];
972 mix_buffer[mix_sample]+=temp*(*vtt)->res_volume_left;
974 mix_buffer[mix_sample]+=temp*(*vtt)->res_volume_right;
977 if (temp>max) max=temp;
978 else if (temp<min) min=temp;
982 if (min>max) (*vtt)->max_value=min; else (*vtt)->max_value=max;
984 if ((*vtt)->ec_enable)
986 for (sample=0, mix_sample=0; sample<(*vtt)->samples_in_outputbuffer; sample++)
988 temp=(*vtt)->ec_output_buffer[sample];
990 mix_buffer[mix_sample]+=temp*(*vtt)->ec_volume_left;
992 mix_buffer[mix_sample]+=temp*(*vtt)->ec_volume_right;
1003 for (sample=0; sample<samples_in_mix_buffer; sample+=2)
1005 temp=mix_buffer[sample];
1008 #define FL_SHRT_MAX 32767.0
1009 #define FL_SHRT_MIN -32768.0
1010 if(temp < FL_SHRT_MIN) temp = FL_SHRT_MIN;
1011 else if (temp > FL_SHRT_MAX) temp = FL_SHRT_MAX;
1014 mix_out_buffer[sample]=(int16_t) temp;
1016 if (temp>max) max=temp;
1017 else if (temp<min) min=temp;
1021 if (min>max) mix_max_l=min; else mix_max_l=max;
1028 for (sample=1; sample<samples_in_mix_buffer; sample+=2)
1030 temp=mix_buffer[sample];
1033 if(temp < FL_SHRT_MIN) temp = FL_SHRT_MIN;
1034 else if (temp > FL_SHRT_MAX) temp = FL_SHRT_MAX;
1037 mix_out_buffer[sample]=(int16_t) temp;
1039 if (temp>max) max=temp;
1040 else if (temp<min) min=temp;
1044 if (min>max) mix_max_r=min; else mix_max_r=max;
1049 vtt=render_list.begin();
1050 while (vtt!=render_list.end())
1055 if ((*vtt)->want_stop) (*vtt)->stop_nolock();
1058 pthread_mutex_unlock(&render_lock);
1060 return(mix_out_buffer);
1063 void vtt_class :: forward_all_turntables()
1065 list <vtt_class *> :: iterator vtt, next;
1067 if (render_list.size()>0)
1069 vtt=render_list.begin();
1070 (*vtt)->forward_turntable();
1072 if (master_triggered)
1074 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
1076 if ((*vtt)->is_sync_client)
1078 if ((*vtt)->sync_countdown)
1080 (*vtt)->sync_countdown--;
1084 (*vtt)->sync_countdown=(*vtt)->sync_cycles;
1091 vtt=render_list.begin();
1092 for (vtt++; vtt!=render_list.end(); vtt++)
1094 (*vtt)->forward_turntable();
1099 vtt=render_list.begin();
1100 while (vtt!=render_list.end())
1105 if ((*vtt)->want_stop) (*vtt)->stop_nolock();
1111 int vtt_class :: trigger()
1113 list <vtt_fx *> :: iterator effect;
1115 if (!buffer) return (1);
1117 if (!is_playing) pthread_mutex_lock(&render_lock);
1119 if (res_pitch>=0) pos_f=0;
1123 speed_real=res_pitch;
1124 speed_target=res_pitch;
1127 /* activating plugins */
1128 for (effect=fx_list.begin(); effect != fx_list.end(); effect++)
1130 (*effect)->activate();
1138 master_triggered_at=0;
1147 render_list.push_front(this);
1151 render_list.push_back(this);
1153 pthread_mutex_unlock(&render_lock);
1158 static bool do_unlock=true;
1160 int vtt_class :: stop_nolock()
1162 list <vtt_fx *> :: iterator effect;
1164 if ((!is_playing) && do_unlock)
1166 pthread_mutex_unlock(&render_lock);
1169 render_list.remove(this);
1178 /* deactivating plugins */
1179 for (effect=fx_list.begin(); effect != fx_list.end(); effect++)
1181 (*effect)->deactivate();
1187 int vtt_class :: stop()
1191 pthread_mutex_lock(&render_lock);
1199 pthread_mutex_unlock(&render_lock);
1204 void vtt_class :: set_sync_master(int master)
1208 if (sync_master) sync_master->set_sync_master(0);
1214 if (sync_master==this) sync_master=0;
1216 gui_clear_master_button(this);
1220 void vtt_class :: set_sync_client(int slave, int cycles)
1222 is_sync_client=slave;
1224 // sync_countdown=cycles;
1228 void vtt_class :: set_sync_client_ug(int slave, int cycles)
1230 set_sync_client(slave, cycles);
1233 void vtt_class :: set_master_volume(f_prec new_volume)
1235 list <vtt_class *> :: iterator vtt;
1237 master_volume=new_volume;
1238 globals.volume=new_volume;
1240 if (main_list.size()>0)
1242 vol_channel_adjust=sqrt((f_prec) main_list.size());
1243 res_master_volume=master_volume/vol_channel_adjust;
1246 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
1248 (*vtt)->recalc_volume();
1252 void vtt_class :: set_master_pitch(f_prec new_pitch)
1254 list <vtt_class *> :: iterator vtt;
1256 globals.pitch=new_pitch;
1257 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
1259 (*vtt)->recalc_pitch();
1263 void vtt_class :: enable_saturate (int newstate)
1265 do_saturate=newstate;
1268 void vtt_class :: focus_no(int no)
1270 list <vtt_class *> :: iterator vtt;
1273 for (i=0, vtt=main_list.begin(); vtt!=main_list.end(); vtt++, i++)
1282 void vtt_class :: focus_next()
1284 list <vtt_class *> :: iterator vtt;
1288 if (main_list.size())
1290 focused_vtt=(*main_list.begin());
1295 for (vtt=main_list.begin(); vtt!=main_list.end() ; vtt++) {
1296 if ((*vtt)==focused_vtt) {
1297 /* Ok, we found ourselves.. */
1300 while ((vtt!=main_list.end()) && ((*vtt)->audio_hidden) ) {
1304 if (vtt==main_list.end()) {
1305 /* No other "focusable" after this vtt so we're looking for the next */
1307 for (vtt=main_list.begin(); vtt!=main_list.end() ; vtt++) {
1308 if (! (*vtt)->audio_hidden) {
1313 /* When we get here there's no "focusable" vtt at all... damn */
1323 focused_vtt=(*main_list.begin());
1326 void vtt_class :: set_scratch(int newstate)
1330 sp_spin.receive_input_value(0);
1332 sense_cycles=globals.sense_cycles;
1336 sp_spin.receive_input_value(1);
1342 void vtt_class :: unfocus()
1347 void vtt_class :: set_x_input_parameter(tX_seqpar *sp)
1352 void vtt_class :: set_y_input_parameter(tX_seqpar *sp)
1357 void vtt_class :: xy_input(f_prec x_value, f_prec y_value)
1359 if (x_par) x_par->handle_mouse_input(x_value*globals.mouse_speed);
1360 if (y_par) y_par->handle_mouse_input(y_value*globals.mouse_speed);
1363 #define store(data); if (fwrite((void *) &data, sizeof(data), 1, output)!=1) res+=1;
1365 int vtt_class :: save(FILE *rc, gzFile rz, char *indent) {
1366 list <vtt_fx *> :: iterator effect;
1367 char tmp_xml_buffer[4096];
1371 tX_store("%s<turntable>\n", indent);
1372 strcat(indent, "\t");
1374 store_string("name", name);
1376 store_string("audiofile", filename);
1378 store_string("audiofile", "");
1380 store_bool("sync_master", is_sync_master);
1381 store_bool("autotrigger", autotrigger);
1382 store_bool_sp("loop", loop, sp_loop);
1384 store_bool_sp("sync_client", is_sync_client, sp_sync_client);
1385 store_int_sp("sync_cycles", sync_cycles, sp_sync_cycles);
1387 store_float_sp("volume", rel_volume, sp_volume);
1388 store_float_sp("pitch", rel_pitch, sp_pitch);
1389 store_bool_sp("mute", mute, sp_mute);
1390 store_float_sp("pan", pan, sp_pan);
1392 store_bool_sp("lowpass_enable", lp_enable, sp_lp_enable);
1393 store_float_sp("lowpass_gain", lp_gain, sp_lp_gain);
1394 store_float_sp("lowpass_reso", lp_reso, sp_lp_reso);
1395 store_float_sp("lowpass_freq", lp_freq, sp_lp_freq);
1397 store_bool_sp("echo_enable", ec_enable, sp_ec_enable);
1398 store_float_sp("echo_length", ec_length, sp_ec_length);
1399 store_float_sp("echo_feedback", ec_feedback, sp_ec_feedback);
1400 store_float_sp("echo_pan", ec_pan, sp_ec_pan);
1401 store_float_sp("echo_volume", ec_volume, sp_ec_volume);
1403 store_id("speed", sp_speed.get_persistence_id());
1404 store_id("trigger", sp_trigger.get_persistence_id());
1405 store_id("spin", sp_spin.get_persistence_id());
1409 store_int("x_axis_mapping", x_par->get_persistence_id());
1413 store_int("y_axis_mapping", y_par->get_persistence_id());
1416 store_bool("audio_panel_hidden", audio_hidden);
1417 store_bool("control_panel_hidden", control_hidden);
1418 store_bool("main_panel_hidden", gui.main_panel->is_hidden());
1419 store_bool("trigger_panel_hidden", gui.trigger_panel->is_hidden());
1420 store_bool("lowpass_panel_hidden", gui.lp_panel->is_hidden());
1421 store_bool("echo_panel_hidden", gui.ec_panel->is_hidden());
1423 store_float("audio_x_zoom", gui_get_audio_x_zoom(this));
1425 tX_store("%s<fx>\n", indent);
1426 strcat(indent, "\t");
1428 for (effect=fx_list.begin(); effect!=fx_list.end(); effect++) {
1429 (*effect)->save(rc, rz, indent);
1431 indent[strlen(indent)-1]=0;
1432 tX_store("%s</fx>\n", indent);
1434 indent[strlen(indent)-1]=0;
1435 tX_store("%s</turntable>\n", indent);
1440 #define TX_XML_SETFILE_VERSION "1.0"
1442 int vtt_class :: save_all(FILE* rc, gzFile rz) {
1444 list <vtt_class *> :: iterator vtt;
1447 tX_seqpar :: create_persistence_ids();
1449 tX_store("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n");
1450 tX_store("<terminatorXset version=\"%s\">\n", TX_XML_SETFILE_VERSION);
1452 strcpy(indent, "\t");
1454 //store_int(vtt_amount); obsolete
1456 store_float_sp("master_volume", master_volume, sp_master_volume);
1457 store_float_sp("master_pitch", globals.pitch, sp_master_pitch);
1459 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++) {
1460 res+=(*vtt)->save(rc, rz, indent);
1463 sequencer.save(rc, rz, indent);
1465 tX_store("</terminatorXset>\n");
1470 int vtt_class :: load(xmlDocPtr doc, xmlNodePtr node) {
1480 char tmp_xml_buffer[4096];
1482 for (xmlNodePtr cur=node->xmlChildrenNode; cur != NULL; cur = cur->next) {
1483 if (cur->type == XML_ELEMENT_NODE) {
1486 restore_string_ac("name", buffer, set_name(buffer));
1487 restore_string("audiofile", filename);
1488 restore_bool("sync_master", is_sync_master);
1489 restore_bool("autotrigger", autotrigger);
1490 restore_bool_id("loop", loop, sp_loop, nop);
1491 restore_bool_id("sync_client", is_sync_client, sp_sync_client, set_sync_client(is_sync_client, sync_cycles));
1492 restore_int_id("sync_cycles", sync_cycles, sp_sync_cycles, set_sync_client(is_sync_client, sync_cycles));
1493 restore_float_id("volume", rel_volume, sp_volume, recalc_volume());
1494 restore_float_id("pitch", rel_pitch, sp_pitch, recalc_pitch());
1495 restore_bool_id("mute", mute, sp_mute, set_mute(mute));
1496 restore_float_id("pan", pan, sp_pan, set_pan(pan));
1498 restore_bool_id("lowpass_enable", lp_enable, sp_lp_enable, lp_set_enable(lp_enable));
1499 restore_float_id("lowpass_gain", lp_gain, sp_lp_gain, lp_set_gain(lp_gain));
1500 restore_float_id("lowpass_reso", lp_reso, sp_lp_reso, lp_set_reso(lp_reso));
1501 restore_float_id("lowpass_freq", lp_freq, sp_lp_freq, lp_set_freq(lp_freq));
1503 restore_bool_id("echo_enable", ec_enable, sp_ec_enable, ec_set_enable(ec_enable));
1504 restore_float_id("echo_length", ec_length, sp_ec_length, ec_set_length(ec_length));
1505 restore_float_id("echo_feedback", ec_feedback, sp_ec_feedback, ec_set_feedback(ec_feedback));
1506 restore_float_id("echo_pan", ec_pan, sp_ec_pan, ec_set_pan(ec_pan));
1507 restore_float_id("echo_volume", ec_volume, sp_ec_volume, ec_set_volume(ec_volume));
1509 restore_id("speed", sp_speed);
1510 restore_id("trigger", sp_trigger);
1511 restore_id("spin", sp_spin);
1513 restore_int("x_axis_mapping", xpar_id);
1514 restore_int("y_axis_mapping", ypar_id);
1516 restore_bool("audio_panel_hidden", audio_hidden);
1517 restore_bool("control_panel_hidden", control_hidden);
1518 restore_bool_ac("main_panel_hidden", hidden, gui.main_panel->hide(hidden));
1519 restore_bool_ac("trigger_panel_hidden", hidden, gui.trigger_panel->hide(hidden));
1520 restore_bool_ac("lowpass_panel_hidden", hidden, gui.lp_panel->hide(hidden));
1521 restore_bool_ac("echo_panel_hidden", hidden, gui.ec_panel->hide(hidden));
1522 restore_float_ac("audio_x_zoom", tmp, gui_set_audio_x_zoom(this,tmp));
1523 vg_adjust_zoom(gui.zoom, this);
1525 if (xmlStrcmp(cur->name, (xmlChar *) "fx")==0) {
1529 for (xmlNodePtr cur=fx->xmlChildrenNode; cur != NULL; cur = cur->next) {
1530 if (cur->type == XML_ELEMENT_NODE) {
1533 if (xmlStrcmp(cur->name, (xmlChar *) "cutoff")==0) {
1534 for (unsigned int t=0; t<fx_list.size(); t++) effect_down(lp_fx);
1536 } else if (xmlStrcmp(cur->name, (xmlChar *) "lowpass")==0) {
1537 for (unsigned int t=0; t<fx_list.size(); t++) effect_down(ec_fx);
1539 } else if (xmlStrcmp(cur->name, (xmlChar *) "ladspa_plugin")==0) {
1540 xmlNodePtr pluginNode=cur;
1544 for (xmlNodePtr cur=pluginNode->xmlChildrenNode; cur!=NULL; cur = cur->next) {
1546 if (cur->type == XML_ELEMENT_NODE) {
1549 restore_int("ladspa_id", ladspa_id);
1550 if (elementFound) break;
1554 if (ladspa_id!=-1) {
1555 LADSPA_Plugin *plugin=LADSPA_Plugin::getPluginByUniqueID(ladspa_id);
1557 vtt_fx_ladspa *ladspa_effect=add_effect(plugin);
1558 ladspa_effect->load(doc, pluginNode);
1560 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);
1561 tx_note(buffer, true);
1564 tX_warning("ladspa_plugin section without a ladspa_id element.");
1568 tX_warning("unhandled element %s in fx section.", cur->name);
1575 tX_warning("unhandled element %s in turntable secion.", cur->name);
1583 set_x_input_parameter(tX_seqpar :: get_sp_by_persistence_id(xpar_id));
1585 else set_x_input_parameter(NULL);
1588 set_y_input_parameter(tX_seqpar :: get_sp_by_persistence_id(ypar_id));
1590 else set_y_input_parameter(NULL);
1595 void vtt_class :: delete_all()
1597 while (main_list.size()) {
1598 delete((*main_list.begin()));
1603 int vtt_class :: load_all(xmlDocPtr doc, char *fname) {
1604 xmlNodePtr root=xmlDocGetRootElement(doc);
1615 tX_error("no root element? What kind of XML document is this?");
1619 if (xmlStrcmp(root->name, (const xmlChar *) "terminatorXset")) {
1620 tX_error("this is not a terminatorXset file.")
1624 if (xmlGetProp(root,(xmlChar *) "version")==NULL) {
1625 tX_error("the set file lacks a version attribute.");
1629 if (xmlStrcmp(xmlGetProp(root, (xmlChar *) "version"), (xmlChar *) TX_XML_SETFILE_VERSION)) {
1630 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);
1633 /* delete current tables... */
1638 /* counting turntables.. */
1639 for (xmlNodePtr cur=root->xmlChildrenNode; cur != NULL; cur = cur->next) {
1640 if (cur->type == XML_ELEMENT_NODE) {
1641 if (xmlStrcmp(cur->name, (xmlChar *) "turntable")==0) {
1647 tX_debug("Found %i turntables in set.", table_ctr);
1649 ld_create_loaddlg(TX_LOADDLG_MODE_MULTI, table_ctr);
1650 ld_set_setname(fname);
1653 for (xmlNodePtr cur=root->xmlChildrenNode; cur != NULL; cur = cur->next) {
1654 if (cur->type == XML_ELEMENT_NODE) {
1657 restore_float_id("master_volume", master_volume, sp_master_volume, set_master_volume(master_volume));
1658 restore_float_id("master_pitch", globals.pitch, sp_master_pitch, set_master_pitch(globals.pitch));
1660 if ((!elementFound) && (xmlStrcmp(cur->name, (xmlChar *) "turntable")==0)) {
1662 vtt_class *vtt=new vtt_class(1);
1663 vtt->load(doc, cur);
1665 tX_debug("loading a turntable..");
1667 if (strlen(vtt->filename)) {
1668 strcpy(fn_buff, vtt->filename);
1669 ld_set_filename(fn_buff);
1671 restmp=(int) vtt->load_file(fn_buff);
1675 gtk_box_pack_start(GTK_BOX(control_parent), vtt->gui.control_box, TRUE, TRUE, 0);
1676 gtk_box_pack_start(GTK_BOX(audio_parent), vtt->gui.audio_box, TRUE, TRUE, 0);
1677 if (vtt->audio_hidden) vtt->hide_audio(vtt->audio_hidden);
1678 if (vtt->control_hidden) vtt->hide_control(vtt->control_hidden);
\r
1680 if ((!elementFound) && (xmlStrcmp(cur->name, (xmlChar *) "sequencer")==0)) {
1682 sequencer.load(doc, cur);
1684 if (!elementFound) {
1685 tX_warning("unhandled element %s in setfile %s", cur->name, fname);
1695 void add_vtt(GtkWidget *ctrl, GtkWidget *audio, char *fn)
1698 hmmpg = new vtt_class(1);
1699 gtk_box_pack_start(GTK_BOX(ctrl), hmmpg->gui.control_box, TRUE, TRUE, 0);
1700 gtk_box_pack_start(GTK_BOX(audio), hmmpg->gui.audio_box, TRUE, TRUE, 0);
1701 if (fn) hmmpg->load_file(fn);
1704 extern void vg_move_fx_panel_up(GtkWidget *wid, vtt_class *vtt);
1705 extern void vg_move_fx_panel_down(GtkWidget *wid, vtt_class *vtt);
1707 //#define debug_fx_stack(); for (i=fx_list.begin(); i != fx_list.end(); i++) puts((*i)->get_info_string());
1708 #define debug_fx_stack();
1710 void vtt_class :: effect_up(vtt_fx *effect)
1712 list <vtt_fx *> :: iterator i;
1713 list <vtt_fx *> :: iterator previous;
1718 if ((*fx_list.begin())==effect) return;
1720 for (previous=i=fx_list.begin(); i != fx_list.end(); i++)
1732 pthread_mutex_lock(&render_lock);
1733 fx_list.remove(effect);
1734 fx_list.insert(previous, effect);
1735 pthread_mutex_unlock(&render_lock);
1737 vg_move_fx_panel_up(effect->get_panel_widget(), this);
1743 void vtt_class :: effect_down(vtt_fx *effect)
1745 list <vtt_fx *> :: iterator i;
1750 for (i=fx_list.begin(); i != fx_list.end(); i++)
1759 if ((ok) && (i!=fx_list.end()))
1762 if (i==fx_list.end()) return;
1765 pthread_mutex_lock(&render_lock);
1766 fx_list.remove(effect);
1768 fx_list.insert(i, effect);
1769 vg_move_fx_panel_down(effect->get_panel_widget(), this);
1770 pthread_mutex_unlock(&render_lock);
1776 void vtt_class :: effect_remove(vtt_fx_ladspa *effect)
1778 pthread_mutex_lock(&render_lock);
1779 fx_list.remove(effect);
1780 pthread_mutex_unlock(&render_lock);
1785 extern void gui_hide_control_panel(vtt_class *vtt, bool hide);
1786 extern void gui_hide_audio_panel(vtt_class *vtt, bool hide);
1788 void vtt_class :: hide_audio(bool hide) {
1790 gui_hide_audio_panel(this, hide);
1793 void vtt_class :: hide_control(bool hide) {
1794 control_hidden=hide;
1795 gui_hide_control_panel(this, hide);
1798 void vtt_class :: set_sample_rate(int samplerate) {
1799 list <vtt_class *> :: iterator vtt;
1800 double sr=(double) samplerate;
1802 last_sample_rate=samplerate;
1804 for (vtt=main_list.begin(); vtt!=main_list.end() ; vtt++) {
1805 if ((*vtt)->audiofile) {
1806 double file_rate=(*vtt)->audiofile->get_sample_rate();
1807 (*vtt)->audiofile_pitch_correction=file_rate/sr;
1809 (*vtt)->audiofile_pitch_correction=1.0;
1811 (*vtt)->recalc_pitch();
1814 int no_samples=(int) (sr*0.001); // Forcing 1 ms blocksize
1816 set_mix_buffer_size(no_samples);
1819 void vtt_class :: adjust_to_master_pitch(int master_cycles, int cycles, bool create_event) {
1820 if (!sync_master) return;
1821 if (this==sync_master) return;
1822 if (!sync_master->audiofile) return;
1823 if (!audiofile) return;
1825 double master_time=((double) master_cycles)/sync_master->rel_pitch*sync_master->audiofile->get_no_samples()/((double) sync_master->audiofile->get_sample_rate());
1826 double my_rel_pitch=((audiofile->get_no_samples()/((double) audiofile->get_sample_rate()))*((double) cycles))/master_time;
1829 sp_pitch.do_exec(my_rel_pitch);
1830 sp_pitch.record_value(my_rel_pitch);
1832 sp_pitch.do_exec(my_rel_pitch);
1835 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());
1837 sp_pitch.update_graphics();