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;
87 vtt_class * vtt_class::sync_master=NULL;
88 int vtt_class::master_triggered=0;
89 int vtt_class::master_triggered_at=0;
90 vtt_class * vtt_class::focused_vtt=NULL;
91 f_prec vtt_class::mix_max_l=0;
92 f_prec vtt_class::mix_max_r=0;
93 f_prec vtt_class::vol_channel_adjust=1.0;
94 int vtt_class::mix_buffer_size=0;
96 #define GAIN_AUTO_ADJUST 0.8
98 vtt_class :: vtt_class (int do_create_gui)
101 sprintf (name, "Turntable %i", vtt_amount);
102 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 if (mix_solo) solo_ctr--;
219 while (fx_list.size())
221 effect=(*fx_list.begin());
222 fx_list.remove(effect);
226 if (sync_master==this) {
233 void vtt_class :: set_name(char *newname)
235 strcpy(name, newname);
236 gui_set_name(this, name);
239 tX_audio_error vtt_class :: load_file(char *fname)
242 int was_playing=is_playing;
244 if (is_playing) stop();
246 if (audiofile) delete(audiofile);
254 audiofile=new tx_audiofile();
255 res=audiofile->load(fname);
257 if (res==TX_AUDIO_SUCCESS) {
258 buffer=audiofile->get_buffer();
259 double file_rate=audiofile->get_sample_rate();
260 audiofile_pitch_correction=file_rate/((double) last_sample_rate);
262 samples_in_buffer=audiofile->get_no_samples();
263 pos_i_max=samples_in_buffer-1;
264 maxpos=audiofile->get_no_samples();
265 strcpy(filename, fname);
266 if (was_playing) trigger();
267 // printf("Successfully loaded %s, %08x, %i\n", fname, buffer, samples_in_buffer);
272 gui_update_display(this);
274 ec_set_length(ec_length);
279 int vtt_class :: set_output_buffer_size(int newsize)
281 list <vtt_fx *> :: iterator effect;
283 if (ec_output_buffer) tX_freemem(ec_output_buffer, "ec_output_buffer", "vtt set_output_buffer_size()");
284 tX_malloc(ec_output_buffer, "ec_output_buffer", "vtt set_output_buffer_size()", sizeof(float)*newsize, (float *));
286 if (output_buffer) tX_freemem(output_buffer, "output_buffer", "vtt set_output_buffer_size()");
287 tX_malloc(output_buffer, "output_buffer", "vtt set_output_buffer_size()", sizeof(float)*newsize, (float *));
289 end_of_outputbuffer = output_buffer + newsize; //size_t(sizeof(float)*(newsize));
291 samples_in_outputbuffer=newsize;
292 inv_samples_in_outputbuffer=1.0/samples_in_outputbuffer;
294 for (effect=fx_list.begin(); effect != fx_list.end(); effect++)
296 (*effect)->reconnect_buffer();
299 if (output_buffer) return(0);
303 void vtt_class :: set_volume(f_prec newvol)
309 void vtt_class :: recalc_volume()
311 res_volume=rel_volume*res_master_volume;
312 f_prec ec_res_volume=res_volume*ec_volume;
316 res_volume_left=(1.0-pan)*res_volume;
317 res_volume_right=res_volume;
321 res_volume_left=res_volume;
322 res_volume_right=(1.0+pan)*res_volume;
326 res_volume_left=res_volume_right=res_volume;
331 ec_volume_left=(1.0-ec_pan)*ec_res_volume;
332 ec_volume_right=ec_res_volume;
336 ec_volume_left=ec_res_volume;
337 ec_volume_right=(1.0+ec_pan)*ec_res_volume;
341 ec_volume_left=ec_volume_right=ec_res_volume;
343 // printf("vtt_volume: %f, %f, l: %f, r: %f\n", rel_volume, res_volume, res_volume_left, res_volume_right);
346 void vtt_class :: set_pan(f_prec newpan)
352 void vtt_class :: set_pitch(f_prec newpitch)
358 void vtt_class :: recalc_pitch()
360 res_pitch=globals.pitch*rel_pitch;
361 res_pitch*=audiofile_pitch_correction;
363 ec_set_length(ec_length);
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++) {
523 void vtt_class :: render()
525 list <vtt_fx *> :: iterator effect;
528 if (sense_cycles>0) {
530 if (sense_cycles==0) sp_speed.receive_input_value(0);
535 for (effect=fx_list.begin(); effect != fx_list.end(); effect++) {
536 if ((*effect)->isEnabled()) (*effect)->run();
540 extern void vg_create_fx_gui(vtt_class *vtt, vtt_fx_ladspa *effect, LADSPA_Plugin *plugin);
542 vtt_fx_ladspa * vtt_class :: add_effect (LADSPA_Plugin *plugin)
544 vtt_fx_ladspa *new_effect;
546 new_effect = new vtt_fx_ladspa (plugin, this);
547 pthread_mutex_lock(&render_lock);
548 fx_list.push_back(new_effect);
549 if (is_playing) new_effect->activate();
550 pthread_mutex_unlock(&render_lock);
551 vg_create_fx_gui(this, new_effect, plugin);
556 void vtt_class :: calc_speed()
562 if (speed != speed_target) {
564 speed_step=speed_target-speed_real;
565 speed_step/=globals.vtt_inertia;
568 if (speed_target != speed_real) {
569 speed_real+=speed_step;
570 if ((speed_step<0) && (speed_real<speed_target)) speed_real=speed_target;
571 else if ((speed_step>0) && (speed_real>speed_target)) speed_real=speed_target;
575 if ((speed_last==0) && (speed_real !=0)) {
580 if ((speed_last!=0) && (speed_real==0)) {
586 speed_last = speed_real;
588 if (res_mute != res_mute_old) {
590 fade_out=1; fade_in=0;
593 fade_in=1; fade_out=0;
596 res_mute_old=res_mute;
598 if (res_mute) do_mute=1;
602 void vtt_class :: render_scratch()
623 for (sample =0,out=output_buffer, fade_vol=0.0; sample < samples_in_outputbuffer;sample++, out++, fade_vol+=inv_samples_in_outputbuffer) {
624 if ((speed_real!=0) || (fade_out)) {
635 master_triggered_at=sample;
641 } else if (pos_f<0) {
648 master_triggered_at=sample;
656 pos_a_f=floor(pos_f);
657 pos_i=(unsigned int) pos_a_f;
659 amount_b=pos_f-pos_a_f;
660 amount_a=1.0-amount_b;
666 sample_a=(f_prec) *ptr;
668 if (pos_i == pos_i_max) {
672 sample_b=(f_prec) *ptr;
675 sample_res=(sample_a*amount_a)+(sample_b*amount_b);
678 sample_res*=fade_vol;
679 } else if (fade_out) {
680 sample_res*=1.0-fade_vol;
691 void vtt_class :: forward_turntable()
702 if ((speed_real==0) && (!fade_out)) return;
705 /* following code is problematic as adding speed_real*n is
706 different from adding speed_real n times to pos_f.
708 well it speeds things up quite a bit and double precision
709 seems to do a satisfying job.
711 #define pos_f_test to prove that.
714 pos_f_tmp=pos_f+speed_real*samples_in_outputbuffer;
716 if ((pos_f_tmp > 0) && (pos_f_tmp < maxpos)) {
725 /* now the slow way ;) */
727 for (sample =0; sample < samples_in_outputbuffer; sample++) {
734 if (is_sync_master) {
736 master_triggered_at=sample;
742 } else if (pos_f<0) {
746 if (is_sync_master) {
748 master_triggered_at=sample;
758 diff=pos_f_tmp-pos_f;
759 if (diff!=0) printf("fast: %f, slow: %f, diff: %f, tt: %s\n", pos_f_tmp, pos_f, diff, name);
765 The following lowpass filter is based on some sample code by
766 Paul Kellett <paul.kellett@maxim.abel.co.uk>
769 void vtt_class :: render_lp()
773 for (sample = output_buffer; sample<end_of_outputbuffer; sample++) {
774 lp_buf0 = lp_a * lp_buf0 + lp_freq * ((*sample)*lp_resgain + lp_b * (lp_buf0 - lp_buf1));
775 lp_buf1 = lp_a * lp_buf1 + lp_freq * lp_buf0;
781 void vtt_class :: render_ec()
787 for (i=0, sample = output_buffer, ec_sample=ec_output_buffer; i<samples_in_outputbuffer; i++, ec_sample++,sample++, ec_ptr++) {
788 if (ec_ptr>ec_delay) ec_ptr=ec_buffer;
789 *ec_sample=(*ec_ptr) *ec_feedback;
790 *ec_ptr=*sample+*ec_sample;
794 int vtt_class :: set_mix_buffer_size(int no_samples)
796 list <vtt_class *> :: iterator vtt;
799 // printf("vtt_class::set_mix_buffer_size(), mix_buffer: %12x, mix_out: %12x, samples: %i\n", mix_buffer, mix_out_buffer, no_samples);
801 if (mix_buffer) tX_freemem(mix_buffer, "mix_buffer", "vtt set_mix_buffer_size()");
802 samples_in_mix_buffer=no_samples*2;
804 tX_malloc(mix_buffer, "mix_buffer", "vtt set_mix_buffer_size()", sizeof(float)*samples_in_mix_buffer, (float *));
805 mix_buffer_end=mix_buffer+samples_in_mix_buffer;
807 // printf("mix_buffer: %12x\n", mix_buffer);
808 // printf("mix_samples: %i, out_samples: %i", samples_in_mix_buffer, no_samples);
810 if (mix_out_buffer) tX_freemem(mix_out_buffer, "mix_out_buffer", "vtt set_mix_buffer_size()");
811 tX_malloc(mix_out_buffer, "mix_out_buffer", "vtt set_mix_buffer_size()", sizeof(int16_t)*samples_in_mix_buffer + 4, (int16_t *));
813 // printf("mix_out_buffer: %12x\n", mix_out_buffer);
815 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) {
838 memset((void *) mix_out_buffer, 0, sizeof(int16_t)*samples_in_mix_buffer);
839 /* We need to memset mix_buffer, too, as the JACK backend
840 acesses this directly.
842 memset((void *) mix_buffer, 0, sizeof(float)*samples_in_mix_buffer);
844 vtt=render_list.begin();
846 max=(*vtt)->max_value;
849 for (sample=0, mix_sample=0; sample<(*vtt)->samples_in_outputbuffer; sample++) {
850 temp=(*vtt)->output_buffer[sample];
851 mix_buffer[mix_sample]=temp*(*vtt)->res_volume_left;
853 mix_buffer[mix_sample]=temp*(*vtt)->res_volume_right;
856 if (temp>max) max=temp;
857 else if (temp<min) min=temp;
861 if (min>max) (*vtt)->max_value=min; else (*vtt)->max_value=max;
863 if ((*vtt)->ec_enable) {
864 for (sample=0, mix_sample=0; sample<(*vtt)->samples_in_outputbuffer; sample++) {
865 temp=(*vtt)->ec_output_buffer[sample];
867 mix_buffer[mix_sample]+=temp*(*vtt)->ec_volume_left;
869 mix_buffer[mix_sample]+=temp*(*vtt)->ec_volume_right;
874 if (master_triggered) {
875 pthread_mutex_unlock(&render_lock);
876 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++) {
877 if ((*vtt)->is_sync_client) {
878 if ((*vtt)->sync_countdown) {
879 (*vtt)->sync_countdown--;
881 (*vtt)->sync_countdown=(*vtt)->sync_cycles;
886 pthread_mutex_lock(&render_lock);
889 vtt=render_list.begin();
890 for (vtt++; vtt!=render_list.end(); vtt++) {
892 max=(*vtt)->max_value;
895 for (sample=0, mix_sample=0; sample<(*vtt)->samples_in_outputbuffer; sample++) {
896 temp=(*vtt)->output_buffer[sample];
897 mix_buffer[mix_sample]+=temp*(*vtt)->res_volume_left;
899 mix_buffer[mix_sample]+=temp*(*vtt)->res_volume_right;
902 if (temp>max) max=temp;
903 else if (temp<min) min=temp;
907 if (min>max) (*vtt)->max_value=min; else (*vtt)->max_value=max;
909 if ((*vtt)->ec_enable) {
910 for (sample=0, mix_sample=0; sample<(*vtt)->samples_in_outputbuffer; sample++) {
911 temp=(*vtt)->ec_output_buffer[sample];
913 mix_buffer[mix_sample]+=temp*(*vtt)->ec_volume_left;
915 mix_buffer[mix_sample]+=temp*(*vtt)->ec_volume_right;
926 for (sample=0; sample<samples_in_mix_buffer; sample+=2) {
927 temp=mix_buffer[sample];
930 #define FL_SHRT_MAX 32767.0
931 #define FL_SHRT_MIN -32768.0
932 if(temp < FL_SHRT_MIN) temp = FL_SHRT_MIN;
933 else if (temp > FL_SHRT_MAX) temp = FL_SHRT_MAX;
936 mix_out_buffer[sample]=(int16_t) temp;
938 if (temp>max) max=temp;
939 else if (temp<min) min=temp;
943 if (min>max) mix_max_l=min; else mix_max_l=max;
950 for (sample=1; sample<samples_in_mix_buffer; sample+=2) {
951 temp=mix_buffer[sample];
954 if(temp < FL_SHRT_MIN) temp = FL_SHRT_MIN;
955 else if (temp > FL_SHRT_MAX) temp = FL_SHRT_MAX;
958 mix_out_buffer[sample]=(int16_t) temp;
960 if (temp>max) max=temp;
961 else if (temp<min) min=temp;
965 if (min>max) mix_max_r=min; else mix_max_r=max;
970 vtt=render_list.begin();
971 while (vtt!=render_list.end()) {
975 if ((*vtt)->want_stop) (*vtt)->stop_nolock();
978 pthread_mutex_unlock(&render_lock);
980 return(mix_out_buffer);
983 void vtt_class :: forward_all_turntables()
985 list <vtt_class *> :: iterator vtt, next;
987 if (render_list.size()>0)
989 vtt=render_list.begin();
990 (*vtt)->forward_turntable();
992 if (master_triggered)
994 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
996 if ((*vtt)->is_sync_client)
998 if ((*vtt)->sync_countdown)
1000 (*vtt)->sync_countdown--;
1004 (*vtt)->sync_countdown=(*vtt)->sync_cycles;
1011 vtt=render_list.begin();
1012 for (vtt++; vtt!=render_list.end(); vtt++)
1014 (*vtt)->forward_turntable();
1019 vtt=render_list.begin();
1020 while (vtt!=render_list.end())
1025 if ((*vtt)->want_stop) (*vtt)->stop_nolock();
1031 int vtt_class :: trigger()
1033 list <vtt_fx *> :: iterator effect;
1035 if (!buffer) return (1);
1037 if (!is_playing) pthread_mutex_lock(&render_lock);
1039 if (res_pitch>=0) pos_f=0;
1043 speed_real=res_pitch;
1044 speed_target=res_pitch;
1047 /* activating plugins */
1048 for (effect=fx_list.begin(); effect != fx_list.end(); effect++)
1050 (*effect)->activate();
1058 master_triggered_at=0;
1067 render_list.push_front(this);
1071 render_list.push_back(this);
1073 pthread_mutex_unlock(&render_lock);
1078 static bool do_unlock=true;
1080 int vtt_class :: stop_nolock()
1082 list <vtt_fx *> :: iterator effect;
1084 if ((!is_playing) && do_unlock) {
1085 pthread_mutex_unlock(&render_lock);
1088 render_list.remove(this);
1097 /* deactivating plugins */
1098 for (effect=fx_list.begin(); effect != fx_list.end(); effect++) {
1099 (*effect)->deactivate();
1105 int vtt_class :: stop()
1109 pthread_mutex_lock(&render_lock);
1117 pthread_mutex_unlock(&render_lock);
1122 void vtt_class :: set_sync_master(int master)
1126 if (sync_master) sync_master->set_sync_master(0);
1132 if (sync_master==this) sync_master=0;
1134 gui_clear_master_button(this);
1138 void vtt_class :: set_sync_client(int slave, int cycles)
1140 is_sync_client=slave;
1142 // sync_countdown=cycles;
1146 void vtt_class :: set_sync_client_ug(int slave, int cycles)
1148 set_sync_client(slave, cycles);
1151 void vtt_class :: set_master_volume(f_prec new_volume)
1153 list <vtt_class *> :: iterator vtt;
1155 master_volume=new_volume;
1156 globals.volume=new_volume;
1158 if (main_list.size()>0)
1160 vol_channel_adjust=sqrt((f_prec) main_list.size());
1161 res_master_volume=master_volume/vol_channel_adjust;
1164 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
1166 (*vtt)->recalc_volume();
1170 void vtt_class :: set_master_pitch(f_prec new_pitch)
1172 list <vtt_class *> :: iterator vtt;
1174 globals.pitch=new_pitch;
1175 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
1177 (*vtt)->recalc_pitch();
1181 void vtt_class :: focus_no(int no)
1183 list <vtt_class *> :: iterator vtt;
1188 for (i=0, vtt=main_list.begin(); vtt!=main_list.end(); vtt++, i++)
1196 void vtt_class :: focus_next()
1198 list <vtt_class *> :: iterator vtt;
1202 if (main_list.size())
1204 focused_vtt=(*main_list.begin());
1209 for (vtt=main_list.begin(); vtt!=main_list.end() ; vtt++) {
1210 if ((*vtt)==focused_vtt) {
1211 /* Ok, we found ourselves.. */
1214 while ((vtt!=main_list.end()) && ((*vtt)->audio_hidden) ) {
1218 if (vtt==main_list.end()) {
1219 /* No other "focusable" after this vtt so we're looking for the next */
1221 for (vtt=main_list.begin(); vtt!=main_list.end() ; vtt++) {
1222 if (! (*vtt)->audio_hidden) {
1227 /* When we get here there's no "focusable" vtt at all... damn */
1237 focused_vtt=(*main_list.begin());
1240 void vtt_class :: set_scratch(int newstate)
1244 sp_spin.receive_input_value(0);
1246 sense_cycles=globals.sense_cycles;
1250 sp_spin.receive_input_value(1);
1256 void vtt_class :: unfocus()
1261 void vtt_class :: set_x_input_parameter(tX_seqpar *sp)
1266 void vtt_class :: set_y_input_parameter(tX_seqpar *sp)
1271 void vtt_class :: xy_input(f_prec x_value, f_prec y_value)
1273 if (x_par) x_par->handle_mouse_input(x_value*globals.mouse_speed);
1274 if (y_par) y_par->handle_mouse_input(y_value*globals.mouse_speed);
1277 #define store(data); if (fwrite((void *) &data, sizeof(data), 1, output)!=1) res+=1;
1279 int vtt_class :: save(FILE *rc, gzFile rz, char *indent) {
1280 list <vtt_fx *> :: iterator effect;
1281 char tmp_xml_buffer[4096];
1285 tX_store("%s<turntable>\n", indent);
1286 strcat(indent, "\t");
1288 store_string("name", name);
1290 store_string("audiofile", filename);
1292 store_string("audiofile", "");
1294 store_bool("sync_master", is_sync_master);
1295 store_bool("autotrigger", autotrigger);
1296 store_bool_sp("loop", loop, sp_loop);
1298 store_bool_sp("sync_client", is_sync_client, sp_sync_client);
1299 store_int_sp("sync_cycles", sync_cycles, sp_sync_cycles);
1301 store_float_sp("volume", rel_volume, sp_volume);
1302 store_float_sp("pitch", rel_pitch, sp_pitch);
1303 store_bool_sp("mute", mute, sp_mute);
1304 store_float_sp("pan", pan, sp_pan);
1306 store_bool_sp("lowpass_enable", lp_enable, sp_lp_enable);
1307 store_float_sp("lowpass_gain", lp_gain, sp_lp_gain);
1308 store_float_sp("lowpass_reso", lp_reso, sp_lp_reso);
1309 store_float_sp("lowpass_freq", lp_freq, sp_lp_freq);
1311 store_bool_sp("echo_enable", ec_enable, sp_ec_enable);
1312 store_float_sp("echo_length", ec_length, sp_ec_length);
1313 store_float_sp("echo_feedback", ec_feedback, sp_ec_feedback);
1314 store_float_sp("echo_pan", ec_pan, sp_ec_pan);
1315 store_float_sp("echo_volume", ec_volume, sp_ec_volume);
1317 store_id("speed", sp_speed.get_persistence_id());
1318 store_id("trigger", sp_trigger.get_persistence_id());
1319 store_id("spin", sp_spin.get_persistence_id());
1323 store_int("x_axis_mapping", x_par->get_persistence_id());
1327 store_int("y_axis_mapping", y_par->get_persistence_id());
1330 store_bool("audio_panel_hidden", audio_hidden);
1331 store_bool("control_panel_hidden", control_hidden);
1332 store_bool("main_panel_hidden", gui.main_panel->is_hidden());
1333 store_bool("trigger_panel_hidden", gui.trigger_panel->is_hidden());
1334 store_bool("lowpass_panel_hidden", gui.lp_panel->is_hidden());
1335 store_bool("echo_panel_hidden", gui.ec_panel->is_hidden());
1337 store_bool("mix_mute", mix_mute);
1338 store_bool("mix_solo", mix_solo);
1340 store_float("audio_x_zoom", gui_get_audio_x_zoom(this));
1342 tX_store("%s<fx>\n", indent);
1343 strcat(indent, "\t");
1345 for (effect=fx_list.begin(); effect!=fx_list.end(); effect++) {
1346 (*effect)->save(rc, rz, indent);
1348 indent[strlen(indent)-1]=0;
1349 tX_store("%s</fx>\n", indent);
1351 indent[strlen(indent)-1]=0;
1352 tX_store("%s</turntable>\n", indent);
1357 #define TX_XML_SETFILE_VERSION "1.0"
1359 int vtt_class :: save_all(FILE* rc, gzFile rz) {
1361 list <vtt_class *> :: iterator vtt;
1364 tX_seqpar :: create_persistence_ids();
1366 tX_store("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n");
1367 tX_store("<terminatorXset version=\"%s\">\n", TX_XML_SETFILE_VERSION);
1369 strcpy(indent, "\t");
1371 //store_int(vtt_amount); obsolete
1373 store_float_sp("master_volume", master_volume, sp_master_volume);
1374 store_float_sp("master_pitch", globals.pitch, sp_master_pitch);
1376 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++) {
1377 res+=(*vtt)->save(rc, rz, indent);
1380 sequencer.save(rc, rz, indent);
1382 tX_store("</terminatorXset>\n");
1387 int vtt_class :: load(xmlDocPtr doc, xmlNodePtr node) {
1397 char tmp_xml_buffer[4096];
1399 for (xmlNodePtr cur=node->xmlChildrenNode; cur != NULL; cur = cur->next) {
1400 if (cur->type == XML_ELEMENT_NODE) {
1403 restore_string_ac("name", buffer, set_name(buffer));
1404 restore_string("audiofile", filename);
1405 restore_bool("sync_master", is_sync_master);
1406 restore_bool("autotrigger", autotrigger);
1407 restore_bool_id("loop", loop, sp_loop, nop);
1408 restore_bool_id("sync_client", is_sync_client, sp_sync_client, set_sync_client(is_sync_client, sync_cycles));
1409 restore_int_id("sync_cycles", sync_cycles, sp_sync_cycles, set_sync_client(is_sync_client, sync_cycles));
1410 restore_float_id("volume", rel_volume, sp_volume, recalc_volume());
1411 restore_float_id("pitch", rel_pitch, sp_pitch, recalc_pitch());
1412 restore_bool_id("mute", mute, sp_mute, set_mute(mute));
1413 restore_float_id("pan", pan, sp_pan, set_pan(pan));
1415 restore_bool_id("lowpass_enable", lp_enable, sp_lp_enable, lp_set_enable(lp_enable));
1416 restore_float_id("lowpass_gain", lp_gain, sp_lp_gain, lp_set_gain(lp_gain));
1417 restore_float_id("lowpass_reso", lp_reso, sp_lp_reso, lp_set_reso(lp_reso));
1418 restore_float_id("lowpass_freq", lp_freq, sp_lp_freq, lp_set_freq(lp_freq));
1420 restore_bool_id("echo_enable", ec_enable, sp_ec_enable, ec_set_enable(ec_enable));
1421 restore_float_id("echo_length", ec_length, sp_ec_length, ec_set_length(ec_length));
1422 restore_float_id("echo_feedback", ec_feedback, sp_ec_feedback, ec_set_feedback(ec_feedback));
1423 restore_float_id("echo_pan", ec_pan, sp_ec_pan, ec_set_pan(ec_pan));
1424 restore_float_id("echo_volume", ec_volume, sp_ec_volume, ec_set_volume(ec_volume));
1426 restore_id("speed", sp_speed);
1427 restore_id("trigger", sp_trigger);
1428 restore_id("spin", sp_spin);
1430 restore_int("x_axis_mapping", xpar_id);
1431 restore_int("y_axis_mapping", ypar_id);
1433 restore_bool("mix_mute", mix_mute);
1434 restore_bool("mix_solo", mix_solo);
1436 restore_bool("audio_panel_hidden", audio_hidden);
1437 restore_bool("control_panel_hidden", control_hidden);
1438 restore_bool_ac("main_panel_hidden", hidden, gui.main_panel->hide(hidden));
1439 restore_bool_ac("trigger_panel_hidden", hidden, gui.trigger_panel->hide(hidden));
1440 restore_bool_ac("lowpass_panel_hidden", hidden, gui.lp_panel->hide(hidden));
1441 restore_bool_ac("echo_panel_hidden", hidden, gui.ec_panel->hide(hidden));
1442 restore_float_ac("audio_x_zoom", tmp, gui_set_audio_x_zoom(this,tmp));
1443 vg_adjust_zoom(gui.zoom, this);
1445 if (xmlStrcmp(cur->name, (xmlChar *) "fx")==0) {
1449 for (xmlNodePtr cur=fx->xmlChildrenNode; cur != NULL; cur = cur->next) {
1450 if (cur->type == XML_ELEMENT_NODE) {
1453 if (xmlStrcmp(cur->name, (xmlChar *) "cutoff")==0) {
1454 for (unsigned int t=0; t<fx_list.size(); t++) effect_down(lp_fx);
1456 } else if (xmlStrcmp(cur->name, (xmlChar *) "lowpass")==0) {
1457 for (unsigned int t=0; t<fx_list.size(); t++) effect_down(ec_fx);
1459 } else if (xmlStrcmp(cur->name, (xmlChar *) "ladspa_plugin")==0) {
1460 xmlNodePtr pluginNode=cur;
1464 for (xmlNodePtr cur=pluginNode->xmlChildrenNode; cur!=NULL; cur = cur->next) {
1466 if (cur->type == XML_ELEMENT_NODE) {
1469 restore_int("ladspa_id", ladspa_id);
1470 if (elementFound) break;
1474 if (ladspa_id!=-1) {
1475 LADSPA_Plugin *plugin=LADSPA_Plugin::getPluginByUniqueID(ladspa_id);
1477 vtt_fx_ladspa *ladspa_effect=add_effect(plugin);
1478 ladspa_effect->load(doc, pluginNode);
1480 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);
1481 tx_note(buffer, true);
1484 tX_warning("ladspa_plugin section without a ladspa_id element.");
1488 tX_warning("unhandled element %s in fx section.", cur->name);
1495 tX_warning("unhandled element %s in turntable secion.", cur->name);
1507 set_x_input_parameter(tX_seqpar :: get_sp_by_persistence_id(xpar_id));
1509 else set_x_input_parameter(NULL);
1512 set_y_input_parameter(tX_seqpar :: get_sp_by_persistence_id(ypar_id));
1514 else set_y_input_parameter(NULL);
1516 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gui.mute), mix_mute);
1517 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gui.solo), mix_solo);
1522 void vtt_class :: delete_all()
1524 while (main_list.size()) {
1525 delete((*main_list.begin()));
1528 /* Take care of the master events.. */
1529 sequencer.delete_all_events(tX_sequencer::DELETE_ALL);
1531 /* Now reset master settings ot the default: */
1532 set_master_pitch(1.0);
1533 set_master_volume(1.0);
1535 sp_master_pitch.do_exec(1.0);
1536 sp_master_pitch.do_update_graphics();
1538 sp_master_volume.do_exec(1.0);
1539 sp_master_volume.do_update_graphics();
1541 /* Remove master MIDI mappings... */
1542 sp_master_pitch.bound_midi_event.type=tX_midievent::NONE;
1543 sp_master_volume.bound_midi_event.type=tX_midievent::NONE;
1549 int vtt_class :: load_all(xmlDocPtr doc, char *fname) {
1550 xmlNodePtr root=xmlDocGetRootElement(doc);
1558 tX_error("no root element? What kind of XML document is this?");
1562 if (xmlStrcmp(root->name, (const xmlChar *) "terminatorXset")) {
1563 tX_error("this is not a terminatorXset file.")
1567 if (xmlGetProp(root,(xmlChar *) "version")==NULL) {
1568 tX_error("the set file lacks a version attribute.");
1572 if (xmlStrcmp(xmlGetProp(root, (xmlChar *) "version"), (xmlChar *) TX_XML_SETFILE_VERSION)) {
1573 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);
1576 /* delete current tables... */
1581 /* counting turntables.. */
1582 for (xmlNodePtr cur=root->xmlChildrenNode; cur != NULL; cur = cur->next) {
1583 if (cur->type == XML_ELEMENT_NODE) {
1584 if (xmlStrcmp(cur->name, (xmlChar *) "turntable")==0) {
1590 tX_debug("Found %i turntables in set.", table_ctr);
1592 ld_create_loaddlg(TX_LOADDLG_MODE_MULTI, table_ctr);
1593 ld_set_setname(fname);
1596 for (xmlNodePtr cur=root->xmlChildrenNode; cur != NULL; cur = cur->next) {
1597 if (cur->type == XML_ELEMENT_NODE) {
1600 restore_float_id("master_volume", master_volume, sp_master_volume, set_master_volume(master_volume));
1601 restore_float_id("master_pitch", globals.pitch, sp_master_pitch, set_master_pitch(globals.pitch));
1603 if ((!elementFound) && (xmlStrcmp(cur->name, (xmlChar *) "turntable")==0)) {
1605 vtt_class *vtt=new vtt_class(1);
1606 vtt->load(doc, cur);
1608 tX_debug("loading a turntable..");
1610 if (strlen(vtt->filename)) {
1611 strcpy(fn_buff, vtt->filename);
1612 ld_set_filename(fn_buff);
1614 restmp=(int) vtt->load_file(fn_buff);
1618 gtk_box_pack_start(GTK_BOX(control_parent), vtt->gui.control_box, TRUE, TRUE, 0);
1619 gtk_box_pack_start(GTK_BOX(audio_parent), vtt->gui.audio_box, TRUE, TRUE, 0);
1620 if (vtt->audio_hidden) vtt->hide_audio(vtt->audio_hidden);
1621 if (vtt->control_hidden) vtt->hide_control(vtt->control_hidden);
\r
1623 if ((!elementFound) && (xmlStrcmp(cur->name, (xmlChar *) "sequencer")==0)) {
1625 sequencer.load(doc, cur);
1627 if (!elementFound) {
1628 tX_warning("unhandled element %s in setfile %s", cur->name, fname);
1633 sp_master_volume.do_update_graphics();
1634 sp_master_pitch.do_update_graphics();
1641 void add_vtt(GtkWidget *ctrl, GtkWidget *audio, char *fn)
1644 hmmpg = new vtt_class(1);
1645 gtk_box_pack_start(GTK_BOX(ctrl), hmmpg->gui.control_box, TRUE, TRUE, 0);
1646 gtk_box_pack_start(GTK_BOX(audio), hmmpg->gui.audio_box, TRUE, TRUE, 0);
1647 if (fn) hmmpg->load_file(fn);
1650 extern void vg_move_fx_panel_up(GtkWidget *wid, vtt_class *vtt);
1651 extern void vg_move_fx_panel_down(GtkWidget *wid, vtt_class *vtt);
1653 //#define debug_fx_stack(); for (i=fx_list.begin(); i != fx_list.end(); i++) puts((*i)->get_info_string());
1654 #define debug_fx_stack();
1656 void vtt_class :: effect_up(vtt_fx *effect)
1658 list <vtt_fx *> :: iterator i;
1659 list <vtt_fx *> :: iterator previous;
1664 if ((*fx_list.begin())==effect) return;
1666 for (previous=i=fx_list.begin(); i != fx_list.end(); i++)
1678 pthread_mutex_lock(&render_lock);
1679 fx_list.remove(effect);
1680 fx_list.insert(previous, effect);
1681 pthread_mutex_unlock(&render_lock);
1683 vg_move_fx_panel_up(effect->get_panel_widget(), this);
1689 void vtt_class :: effect_down(vtt_fx *effect)
1691 list <vtt_fx *> :: iterator i;
1696 for (i=fx_list.begin(); i != fx_list.end(); i++)
1705 if ((ok) && (i!=fx_list.end()))
1708 if (i==fx_list.end()) return;
1711 pthread_mutex_lock(&render_lock);
1712 fx_list.remove(effect);
1714 fx_list.insert(i, effect);
1715 vg_move_fx_panel_down(effect->get_panel_widget(), this);
1716 pthread_mutex_unlock(&render_lock);
1722 void vtt_class :: effect_remove(vtt_fx_ladspa *effect)
1724 pthread_mutex_lock(&render_lock);
1725 fx_list.remove(effect);
1726 pthread_mutex_unlock(&render_lock);
1731 extern void gui_hide_control_panel(vtt_class *vtt, bool hide);
1732 extern void gui_hide_audio_panel(vtt_class *vtt, bool hide);
1734 void vtt_class :: hide_audio(bool hide) {
1736 gui_hide_audio_panel(this, hide);
1739 void vtt_class :: hide_control(bool hide) {
1740 control_hidden=hide;
1741 gui_hide_control_panel(this, hide);
1744 void vtt_class :: set_sample_rate(int samplerate) {
1745 list <vtt_class *> :: iterator vtt;
1746 double sr=(double) samplerate;
1748 last_sample_rate=samplerate;
1750 for (vtt=main_list.begin(); vtt!=main_list.end() ; vtt++) {
1751 if ((*vtt)->audiofile) {
1752 double file_rate=(*vtt)->audiofile->get_sample_rate();
1753 (*vtt)->audiofile_pitch_correction=file_rate/sr;
1755 (*vtt)->audiofile_pitch_correction=1.0;
1757 (*vtt)->recalc_pitch();
1760 int no_samples=(int) (sr*0.001); // Forcing 1 ms blocksize
1762 set_mix_buffer_size(no_samples);
1765 void vtt_class :: adjust_to_master_pitch(int master_cycles, int cycles, bool create_event) {
1766 if (!sync_master) return;
1767 if (this==sync_master) return;
1768 if (!sync_master->audiofile) return;
1769 if (!audiofile) return;
1771 double master_time=((double) master_cycles)/sync_master->rel_pitch*sync_master->audiofile->get_no_samples()/((double) sync_master->audiofile->get_sample_rate());
1772 double my_rel_pitch=((audiofile->get_no_samples()/((double) audiofile->get_sample_rate()))*((double) cycles))/master_time;
1775 sp_pitch.do_exec(my_rel_pitch);
1776 sp_pitch.record_value(my_rel_pitch);
1778 sp_pitch.do_exec(my_rel_pitch);
1781 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());
1783 sp_pitch.update_graphics();