2 terminatorX - realtime audio scratching software
3 Copyright (C) 1999-2004 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"
42 #include "tX_loaddlg.h"
44 #define USE_PREFETCH 1
47 #define my_prefetch(base, index); __asm__ __volatile__ ("prefetch index(%0)\n" : : "r" (base));
48 #define my_prefetchw(base, index); __asm__ __volatile__ ("prefetchw index(%0)\n" : : "r" (base));
50 #define my_prefetch(base, index); /* NOP */;
51 #define my_prefetchw(base, index); /* NOP */;
54 extern void build_vtt_gui(vtt_class *);
55 extern void gui_set_name(vtt_class *vtt, char *newname);
56 extern void gui_set_filename(vtt_class *vtt, char *newname);
57 extern void delete_gui(vtt_class *vtt);
58 extern void gui_update_display(vtt_class *vtt);
59 extern void gui_clear_master_button(vtt_class *vtt);
60 extern void cleanup_vtt(vtt_class *vtt);
61 extern int vg_get_current_page(vtt_class *vtt);
62 extern f_prec gui_get_audio_x_zoom(vtt_class *vtt);
63 extern void gui_set_audio_x_zoom(vtt_class *vtt, f_prec);
65 int vtt_class::last_sample_rate=44100;
66 int vtt_class::vtt_amount=0;
67 list <vtt_class *> vtt_class::main_list;
68 list <vtt_class *> vtt_class::render_list;
69 int16_t* vtt_class::mix_out_buffer=NULL;
70 f_prec * vtt_class::mix_buffer=NULL;
71 f_prec * vtt_class::mix_buffer_end=NULL;
72 int vtt_class::solo_ctr=0;
74 int vtt_class::samples_in_mix_buffer=0;
75 pthread_mutex_t vtt_class::render_lock=PTHREAD_MUTEX_INITIALIZER;
76 f_prec vtt_class::master_volume=1.0;
77 f_prec vtt_class::res_master_volume=1.0;
79 vtt_class * vtt_class::sync_master=NULL;
80 int vtt_class::master_triggered=0;
81 int vtt_class::master_triggered_at=0;
82 vtt_class * vtt_class::focused_vtt=NULL;
83 f_prec vtt_class::mix_max_l=0;
84 f_prec vtt_class::mix_max_r=0;
85 f_prec vtt_class::vol_channel_adjust=1.0;
86 int vtt_class::mix_buffer_size=0;
88 #define GAIN_AUTO_ADJUST 0.8
90 vtt_class :: vtt_class (int do_create_gui)
93 cleanup_required=false;
95 sprintf (name, "Turntable %i", vtt_amount);
96 strcpy(filename, "NONE");
105 audiofile_pitch_correction=1.0;
107 ec_output_buffer=NULL;
127 lp_setup(lp_gain, lp_reso, lp_freq);
138 main_list.push_back(this);
140 /* "connecting" the seq-parameters */
142 sp_speed.set_vtt((void *) this);
143 sp_volume.set_vtt((void *) this);
144 sp_pitch.set_vtt((void *) this);
145 sp_pan.set_vtt((void *) this);
146 sp_trigger.set_vtt((void *) this);
147 sp_loop.set_vtt((void *) this);
148 sp_sync_client.set_vtt((void *) this);
149 sp_sync_cycles.set_vtt((void *) this);
150 sp_lp_enable.set_vtt((void *) this);
151 sp_lp_gain.set_vtt((void *) this);
152 sp_lp_reso.set_vtt((void *) this);
153 sp_lp_freq.set_vtt((void *) this);
154 sp_ec_enable.set_vtt((void *) this);
155 sp_ec_length.set_vtt((void *) this);
156 sp_ec_pan.set_vtt((void *) this);
157 sp_ec_volume.set_vtt((void *) this);
158 sp_ec_feedback.set_vtt((void *) this);
159 sp_mute.set_vtt((void *) this);
160 sp_spin.set_vtt((void *) this);
165 lp_fx=new vtt_fx_lp();
166 lp_fx->set_vtt((void *) this);
167 fx_list.push_back(lp_fx);
169 ec_fx=new vtt_fx_ec();
170 ec_fx->set_vtt((void *) this);
171 fx_list.push_back(ec_fx);
176 lp_fx->set_panel_widget(gui.lp_panel->get_widget());
177 ec_fx->set_panel_widget(gui.ec_panel->get_widget());
182 set_master_volume(globals.volume);
183 set_output_buffer_size(samples_in_mix_buffer/2);
186 audiofile_pitch_correction=1.0;
194 control_hidden=false;
201 vtt_class :: ~vtt_class()
206 main_list.remove(this);
207 if (audiofile) delete audiofile;
208 //if (buffer) free(buffer);
209 if (output_buffer) tX_freemem(output_buffer, "output_buffer", "vtt Destructor");
210 if (output_buffer2) tX_freemem(output_buffer2, "output_buffer2", "vtt Destructor");
214 if (mix_solo) solo_ctr--;
216 while (fx_list.size())
218 effect=(*fx_list.begin());
219 fx_list.remove(effect);
223 if (sync_master==this) {
230 void vtt_class :: set_name(char *newname)
232 strcpy(name, newname);
233 gui_set_name(this, name);
236 tX_audio_error vtt_class :: load_file(char *fname)
239 int was_playing=is_playing;
241 if (is_playing) stop();
243 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 pos_i_max=samples_in_buffer-1;
261 maxpos=audiofile->get_no_samples();
262 strcpy(filename, fname);
263 if (was_playing) trigger();
264 // printf("Successfully loaded %s, %08x, %i\n", fname, buffer, samples_in_buffer);
269 gui_update_display(this);
271 ec_set_length(ec_length);
276 int vtt_class :: set_output_buffer_size(int newsize)
278 list <vtt_fx *> :: iterator effect;
280 if (ec_output_buffer) tX_freemem(ec_output_buffer, "ec_output_buffer", "vtt set_output_buffer_size()");
281 tX_malloc(ec_output_buffer, "ec_output_buffer", "vtt set_output_buffer_size()", sizeof(float)*newsize, (float *));
283 if (output_buffer) tX_freemem(output_buffer, "output_buffer", "vtt set_output_buffer_size()");
284 tX_malloc(output_buffer, "output_buffer", "vtt set_output_buffer_size()", sizeof(float)*newsize, (float *));
285 if (output_buffer2) tX_freemem(output_buffer2, "output_buffer2", "vtt set_output_buffer2_size()");
286 tX_malloc(output_buffer2, "output_buffer2", "vtt set_output_buffer2_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();
301 void vtt_class :: set_volume(f_prec newvol)
307 void vtt_class :: recalc_volume()
309 res_volume=rel_volume*res_master_volume;
310 f_prec ec_res_volume=res_volume*ec_volume;
314 res_volume_left=(1.0-pan)*res_volume;
315 res_volume_right=res_volume;
319 res_volume_left=res_volume;
320 res_volume_right=(1.0+pan)*res_volume;
324 res_volume_left=res_volume_right=res_volume;
329 ec_volume_left=(1.0-ec_pan)*ec_res_volume;
330 ec_volume_right=ec_res_volume;
334 ec_volume_left=ec_res_volume;
335 ec_volume_right=(1.0+ec_pan)*ec_res_volume;
339 ec_volume_left=ec_volume_right=ec_res_volume;
341 // printf("vtt_volume: %f, %f, l: %f, r: %f\n", rel_volume, res_volume, res_volume_left, res_volume_right);
344 void vtt_class :: set_pan(f_prec newpan)
350 void vtt_class :: set_pitch(f_prec newpitch)
356 void vtt_class :: recalc_pitch()
358 res_pitch=globals.pitch*rel_pitch;
359 res_pitch*=audiofile_pitch_correction;
361 ec_set_length(ec_length);
364 void vtt_class :: set_autotrigger(int newstate)
366 autotrigger=newstate;
369 void vtt_class :: set_loop(int newstate)
374 void vtt_class :: set_mute(int newstate)
380 void vtt_class :: set_mix_mute(int newstate)
386 void vtt_class :: set_mix_solo(int newstate)
388 if (mix_solo && !newstate)
394 else if (!mix_solo && newstate)
403 list <vtt_class *> :: iterator vtt;
405 for (vtt=main_list.begin(); vtt!=main_list.end() ; vtt++)
411 void vtt_class :: lp_set_enable (int newstate)
417 void vtt_class :: lp_reset()
422 void vtt_class :: lp_set_gain (f_prec gain)
425 lp_resgain=lp_gain*lp_autogain;
428 void vtt_class :: lp_set_reso(f_prec reso)
432 lp_b=reso*(1.0+(1.0/lp_a));
433 lp_autogain=1.0-reso*GAIN_AUTO_ADJUST;
434 lp_resgain=lp_gain*lp_autogain;
437 void vtt_class :: lp_set_freq(f_prec freq)
442 lp_b=lp_reso*(1.0+(1.0/lp_a));
445 void vtt_class :: lp_setup(f_prec gain, f_prec reso, f_prec freq)
451 lp_b=reso*(1.0+(1.0/lp_a));
453 lp_autogain=1.0-reso*GAIN_AUTO_ADJUST;
454 lp_resgain=lp_gain*lp_autogain;
457 void vtt_class :: ec_set_enable(int newstate)
464 void vtt_class :: ec_set_pan(f_prec pan)
471 /* Max length is 1.0 */
473 void vtt_class :: ec_set_length(f_prec length)
480 ec_res_length=length*samples_in_buffer;
484 ec_res_length=length*samples_in_buffer/res_pitch;
487 if (ec_res_length<0) ec_res_length*=-1;
489 if (ec_res_length>=EC_MAX_BUFFER)
491 ec_res_length=EC_MAX_BUFFER*length;
494 delay=(int )floor(ec_res_length);
496 ec_delay=&ec_buffer[delay];
499 void vtt_class :: ec_set_feedback(f_prec feedback)
501 ec_feedback=feedback;
505 void vtt_class :: ec_set_volume(f_prec volume)
511 void vtt_class :: ec_clear_buffer()
515 for (ptr=ec_buffer; ptr<=ec_delay; ptr++) {
519 memset(ec_buffer, 0, sizeof(ec_buffer));
523 #ifdef BIG_ENDIAN_MACHINE
524 #define vabs(x) fabs(x)
526 inline float vabs(float f)
528 int i=((*(int*)&f)&0x7fffffff);
529 return (*(float*)&i);
533 void vtt_class :: render()
535 list <vtt_fx *> :: iterator effect;
538 if (sense_cycles>0) {
540 if (sense_cycles==0) sp_speed.receive_input_value(0);
545 for (effect=fx_list.begin(); effect != fx_list.end(); effect++) {
546 if ((*effect)->isEnabled()) (*effect)->run();
549 if (stereo_fx_list.size()>0) {
551 memcpy((void *) output_buffer2, (void *) output_buffer, sizeof(float)*((int)samples_in_outputbuffer));
553 // apply stereo effects.
554 list <vtt_fx_stereo_ladspa *> :: iterator stereo_effect;
556 for (stereo_effect=stereo_fx_list.begin(); stereo_effect != stereo_fx_list.end(); stereo_effect++) {
557 if ((*stereo_effect)->isEnabled()) (*stereo_effect)->run();
560 for (int sample=0; sample<samples_in_outputbuffer; sample++) {
561 output_buffer[sample]*=res_volume_left;
562 output_buffer2[sample]*=res_volume_right;
565 for (int sample=0; sample<samples_in_outputbuffer; sample++) {
566 output_buffer2[sample]=output_buffer[sample]*res_volume_right;
567 output_buffer[sample]*=res_volume_left;
572 for (int sample=0; sample<samples_in_outputbuffer; sample++) {
573 f_prec temp=ec_output_buffer[sample];
574 output_buffer[sample]+=temp*ec_volume_left;
575 output_buffer2[sample]+=temp*ec_volume_right;
579 // find max signal for vu meters...
580 for (int sample=0; sample<samples_in_outputbuffer; sample++) {
581 f_prec lmax=vabs(output_buffer[sample]);
582 f_prec rmax=vabs(output_buffer2[sample]);
584 if (lmax>max_value) max_value=lmax;
585 if (rmax>max_value2) max_value2=rmax;
589 extern void vg_create_fx_gui(vtt_class *vtt, vtt_fx_ladspa *effect, LADSPA_Plugin *plugin);
591 vtt_fx_ladspa * vtt_class :: add_effect (LADSPA_Plugin *plugin)
593 vtt_fx_ladspa *new_effect;
595 new_effect = new vtt_fx_ladspa (plugin, this);
596 pthread_mutex_lock(&render_lock);
597 fx_list.push_back(new_effect);
598 if (is_playing) new_effect->activate();
599 pthread_mutex_unlock(&render_lock);
600 vg_create_fx_gui(this, new_effect, plugin);
605 vtt_fx_stereo_ladspa * vtt_class :: add_stereo_effect (LADSPA_Stereo_Plugin *plugin)
607 vtt_fx_stereo_ladspa *new_effect;
609 new_effect = new vtt_fx_stereo_ladspa(plugin, this);
610 pthread_mutex_lock(&render_lock);
611 stereo_fx_list.push_back(new_effect);
612 if (is_playing) new_effect->activate();
613 pthread_mutex_unlock(&render_lock);
614 vg_create_fx_gui(this, new_effect, plugin);
619 void vtt_class :: calc_speed()
625 if (speed != speed_target) {
627 speed_step=speed_target-speed_real;
628 speed_step/=globals.vtt_inertia;
631 if (speed_target != speed_real) {
632 speed_real+=speed_step;
633 if ((speed_step<0) && (speed_real<speed_target)) speed_real=speed_target;
634 else if ((speed_step>0) && (speed_real>speed_target)) speed_real=speed_target;
638 if ((speed_last==0) && (speed_real !=0)) {
643 if ((speed_last!=0) && (speed_real==0)) {
649 speed_last = speed_real;
651 if (res_mute != res_mute_old) {
653 fade_out=1; fade_in=0;
656 fade_in=1; fade_out=0;
659 res_mute_old=res_mute;
661 if (res_mute) do_mute=1;
665 void vtt_class :: render_scratch()
686 for (sample =0,out=output_buffer, fade_vol=0.0; sample < samples_in_outputbuffer;sample++, out++, fade_vol+=inv_samples_in_outputbuffer) {
687 if ((speed_real!=0) || (fade_out)) {
698 master_triggered_at=sample;
704 } else if (pos_f<0) {
711 master_triggered_at=sample;
719 pos_a_f=floor(pos_f);
720 pos_i=(unsigned int) pos_a_f;
722 amount_b=pos_f-pos_a_f;
723 amount_a=1.0-amount_b;
729 sample_a=(f_prec) *ptr;
731 if (pos_i == pos_i_max) {
735 sample_b=(f_prec) *ptr;
738 sample_res=(sample_a*amount_a)+(sample_b*amount_b);
740 // scale to 0 db := 1.0f
741 sample_res/=FL_SHRT_MAX;
744 sample_res*=fade_vol;
745 } else if (fade_out) {
746 sample_res*=1.0-fade_vol;
757 void vtt_class :: forward_turntable()
768 if ((speed_real==0) && (!fade_out)) return;
771 /* following code is problematic as adding speed_real*n is
772 different from adding speed_real n times to pos_f.
774 well it speeds things up quite a bit and double precision
775 seems to do a satisfying job.
777 #define pos_f_test to prove that.
780 pos_f_tmp=pos_f+speed_real*samples_in_outputbuffer;
782 if ((pos_f_tmp > 0) && (pos_f_tmp < maxpos)) {
791 /* now the slow way ;) */
793 for (sample =0; sample < samples_in_outputbuffer; sample++) {
800 if (is_sync_master) {
802 master_triggered_at=sample;
808 } else if (pos_f<0) {
812 if (is_sync_master) {
814 master_triggered_at=sample;
824 diff=pos_f_tmp-pos_f;
825 if (diff!=0) printf("fast: %f, slow: %f, diff: %f, tt: %s\n", pos_f_tmp, pos_f, diff, name);
831 The following lowpass filter is based on some sample code by
832 Paul Kellett <paul.kellett@maxim.abel.co.uk>
835 void vtt_class :: render_lp()
839 for (sample = output_buffer; sample<end_of_outputbuffer; sample++) {
840 lp_buf0 = lp_a * lp_buf0 + lp_freq * ((*sample)*lp_resgain + lp_b * (lp_buf0 - lp_buf1));
841 lp_buf1 = lp_a * lp_buf1 + lp_freq * lp_buf0;
847 void vtt_class :: render_ec()
853 for (i=0, sample = output_buffer, ec_sample=ec_output_buffer; i<samples_in_outputbuffer; i++, ec_sample++,sample++, ec_ptr++) {
854 if (ec_ptr>ec_delay) ec_ptr=ec_buffer;
855 *ec_sample=(*ec_ptr) *ec_feedback;
856 *ec_ptr=*sample+*ec_sample;
860 int vtt_class :: set_mix_buffer_size(int no_samples)
862 list <vtt_class *> :: iterator vtt;
865 // printf("vtt_class::set_mix_buffer_size(), mix_buffer: %12x, mix_out: %12x, samples: %i\n", mix_buffer, mix_out_buffer, no_samples);
867 if (mix_buffer) tX_freemem(mix_buffer, "mix_buffer", "vtt set_mix_buffer_size()");
868 samples_in_mix_buffer=no_samples*2;
870 tX_malloc(mix_buffer, "mix_buffer", "vtt set_mix_buffer_size()", sizeof(float)*samples_in_mix_buffer, (float *));
871 mix_buffer_end=mix_buffer+samples_in_mix_buffer;
873 // printf("mix_buffer: %12x\n", mix_buffer);
874 // printf("mix_samples: %i, out_samples: %i", samples_in_mix_buffer, no_samples);
876 if (mix_out_buffer) tX_freemem(mix_out_buffer, "mix_out_buffer", "vtt set_mix_buffer_size()");
877 tX_malloc(mix_out_buffer, "mix_out_buffer", "vtt set_mix_buffer_size()", sizeof(int16_t)*samples_in_mix_buffer + 4, (int16_t *));
879 // printf("mix_out_buffer: %12x\n", mix_out_buffer);
881 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++) {
882 res|=(*vtt)->set_output_buffer_size(no_samples);
885 if ((!mix_buffer) || (!mix_out_buffer) || res) return(1);
887 mix_buffer_size=no_samples;
892 int16_t * vtt_class :: render_all_turntables()
894 list <vtt_class *> :: iterator vtt, next;
901 pthread_mutex_lock(&render_lock);
903 if (render_list.size()==0) {
904 memset((void *) mix_out_buffer, 0, sizeof(int16_t)*samples_in_mix_buffer);
905 /* We need to memset mix_buffer, too, as the JACK backend
906 acesses this directly.
908 memset((void *) mix_buffer, 0, sizeof(float)*samples_in_mix_buffer);
910 vtt=render_list.begin();
913 for (sample=0, mix_sample=0; sample<(*vtt)->samples_in_outputbuffer; sample++) {
914 mix_buffer[mix_sample++]=(*vtt)->output_buffer[sample]*FL_SHRT_MAX;
915 mix_buffer[mix_sample++]=(*vtt)->output_buffer2[sample]*FL_SHRT_MAX;
918 if (master_triggered) {
919 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++) {
920 if ((*vtt)->is_sync_client) {
921 if ((*vtt)->sync_countdown) {
922 (*vtt)->sync_countdown--;
924 (*vtt)->sync_countdown=(*vtt)->sync_cycles;
925 (*vtt)->trigger(false);
931 vtt=render_list.begin();
933 for (vtt++; vtt!=render_list.end(); vtt++) {
936 for (sample=0, mix_sample=0; sample<(*vtt)->samples_in_outputbuffer; sample++) {
937 mix_buffer[mix_sample++]+=(*vtt)->output_buffer[sample]*FL_SHRT_MAX;
938 mix_buffer[mix_sample++]+=(*vtt)->output_buffer2[sample]*FL_SHRT_MAX;
947 for (sample=0; sample<samples_in_mix_buffer; sample+=2) {
948 temp=mix_buffer[sample];
951 if(temp < FL_SHRT_MIN) temp = FL_SHRT_MIN;
952 else if (temp > FL_SHRT_MAX) temp = FL_SHRT_MAX;
955 mix_out_buffer[sample]=(int16_t) temp;
957 if (temp>max) max=temp;
958 else if (temp<min) min=temp;
962 if (min>max) mix_max_l=min; else mix_max_l=max;
969 for (sample=1; sample<samples_in_mix_buffer; sample+=2) {
970 temp=mix_buffer[sample];
973 if(temp < FL_SHRT_MIN) temp = FL_SHRT_MIN;
974 else if (temp > FL_SHRT_MAX) temp = FL_SHRT_MAX;
977 mix_out_buffer[sample]=(int16_t) temp;
979 if (temp>max) max=temp;
980 else if (temp<min) min=temp;
984 if (min>max) mix_max_r=min; else mix_max_r=max;
989 vtt=render_list.begin();
990 while (vtt!=render_list.end()) {
994 if ((*vtt)->want_stop) (*vtt)->stop_nolock();
997 pthread_mutex_unlock(&render_lock);
999 return(mix_out_buffer);
1002 void vtt_class :: forward_all_turntables()
1004 list <vtt_class *> :: iterator vtt, next;
1006 if (render_list.size()>0)
1008 vtt=render_list.begin();
1009 (*vtt)->forward_turntable();
1011 if (master_triggered)
1013 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
1015 if ((*vtt)->is_sync_client)
1017 if ((*vtt)->sync_countdown)
1019 (*vtt)->sync_countdown--;
1023 (*vtt)->sync_countdown=(*vtt)->sync_cycles;
1030 vtt=render_list.begin();
1031 for (vtt++; vtt!=render_list.end(); vtt++)
1033 (*vtt)->forward_turntable();
1038 vtt=render_list.begin();
1039 while (vtt!=render_list.end())
1044 if ((*vtt)->want_stop) (*vtt)->stop_nolock();
1049 void vtt_class :: retrigger()
1051 if (res_pitch>=0) pos_f=0;
1056 speed_real=res_pitch;
1057 speed_target=res_pitch;
1063 if (is_sync_master) {
1065 master_triggered_at=0;
1069 int vtt_class :: trigger(bool need_lock)
1071 if (!buffer) return 1;
1076 if (need_lock) pthread_mutex_lock(&render_lock);
1078 cleanup_required=false;
1080 /* activating plugins */
1081 for (list <vtt_fx *> :: iterator effect=fx_list.begin(); effect != fx_list.end(); effect++) {
1082 (*effect)->activate();
1085 for (list <vtt_fx_stereo_ladspa *> :: iterator effect=stereo_fx_list.begin(); effect != stereo_fx_list.end(); effect++) {
1086 (*effect)->activate();
1089 if (is_sync_master) {
1090 render_list.push_front(this);
1092 render_list.push_back(this);
1095 if (need_lock) pthread_mutex_unlock(&render_lock);
1101 /* call this only when owning render_lock. */
1102 int vtt_class :: stop_nolock()
1104 list <vtt_fx *> :: iterator effect;
1110 render_list.remove(this);
1116 cleanup_required=true;
1118 /* deactivating plugins */
1119 for (effect=fx_list.begin(); effect != fx_list.end(); effect++) {
1120 (*effect)->deactivate();
1126 int vtt_class :: stop()
1130 pthread_mutex_lock(&render_lock);
1132 pthread_mutex_unlock(&render_lock);
1137 void vtt_class :: set_sync_master(int master)
1140 if (sync_master) sync_master->set_sync_master(0);
1144 if (sync_master==this) sync_master=0;
1146 gui_clear_master_button(this);
1150 void vtt_class :: set_sync_client(int slave, int cycles)
1152 tX_debug("vtt_class::set_sync_client() setting %i, %i.", slave, cycles);
1153 is_sync_client=slave;
1155 // sync_countdown=cycles;
1159 void vtt_class :: set_sync_client_ug(int slave, int cycles)
1161 set_sync_client(slave, cycles);
1164 void vtt_class :: set_master_volume(f_prec new_volume)
1166 list <vtt_class *> :: iterator vtt;
1168 master_volume=new_volume;
1169 globals.volume=new_volume;
1171 if (main_list.size()>0) {
1172 vol_channel_adjust=sqrt((f_prec) main_list.size());
1173 res_master_volume=master_volume/vol_channel_adjust;
1176 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++) {
1177 (*vtt)->recalc_volume();
1181 void vtt_class :: set_master_pitch(f_prec new_pitch)
1183 list <vtt_class *> :: iterator vtt;
1185 globals.pitch=new_pitch;
1186 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++) {
1187 (*vtt)->recalc_pitch();
1191 void vtt_class :: focus_no(int no)
1193 list <vtt_class *> :: iterator vtt;
1198 for (i=0, vtt=main_list.begin(); vtt!=main_list.end(); vtt++, i++) {
1205 void vtt_class :: focus_next()
1207 list <vtt_class *> :: iterator vtt;
1210 if (main_list.size()) {
1211 focused_vtt=(*main_list.begin());
1216 for (vtt=main_list.begin(); vtt!=main_list.end() ; vtt++) {
1217 if ((*vtt)==focused_vtt) {
1218 /* Ok, we found ourselves.. */
1221 while ((vtt!=main_list.end()) && ((*vtt)->audio_hidden) ) {
1225 if (vtt==main_list.end()) {
1226 /* No other "focusable" after this vtt so we're looking for the next */
1228 for (vtt=main_list.begin(); vtt!=main_list.end() ; vtt++) {
1229 if (! (*vtt)->audio_hidden) {
1234 /* When we get here there's no "focusable" vtt at all... damn */
1244 focused_vtt=(*main_list.begin());
1247 void vtt_class :: set_scratch(int newstate)
1250 sp_spin.receive_input_value(0);
1252 sense_cycles=globals.sense_cycles;
1254 sp_spin.receive_input_value(1);
1260 void vtt_class :: unfocus()
1265 void vtt_class :: set_x_input_parameter(tX_seqpar *sp)
1270 void vtt_class :: set_y_input_parameter(tX_seqpar *sp)
1275 void vtt_class :: xy_input(f_prec x_value, f_prec y_value)
1277 if (x_par) x_par->handle_mouse_input(x_value*globals.mouse_speed);
1278 if (y_par) y_par->handle_mouse_input(y_value*globals.mouse_speed);
1281 #define store(data); if (fwrite((void *) &data, sizeof(data), 1, output)!=1) res+=1;
1283 int vtt_class :: save(FILE *rc, gzFile rz, char *indent) {
1284 char tmp_xml_buffer[4096];
1288 tX_store("%s<turntable>\n", indent);
1289 strcat(indent, "\t");
1291 store_string("name", name);
1293 store_string("audiofile", filename);
1295 store_string("audiofile", "");
1297 store_bool("sync_master", is_sync_master);
1298 store_bool("autotrigger", autotrigger);
1299 store_bool_sp("loop", loop, sp_loop);
1301 store_bool_sp("sync_client", is_sync_client, sp_sync_client);
1302 store_int_sp("sync_cycles", sync_cycles, sp_sync_cycles);
1304 store_float_sp("volume", rel_volume, sp_volume);
1305 store_float_sp("pitch", rel_pitch, sp_pitch);
1306 store_bool_sp("mute", mute, sp_mute);
1307 store_float_sp("pan", pan, sp_pan);
1309 store_bool_sp("lowpass_enable", lp_enable, sp_lp_enable);
1310 store_float_sp("lowpass_gain", lp_gain, sp_lp_gain);
1311 store_float_sp("lowpass_reso", lp_reso, sp_lp_reso);
1312 store_float_sp("lowpass_freq", lp_freq, sp_lp_freq);
1314 store_bool_sp("echo_enable", ec_enable, sp_ec_enable);
1315 store_float_sp("echo_length", ec_length, sp_ec_length);
1316 store_float_sp("echo_feedback", ec_feedback, sp_ec_feedback);
1317 store_float_sp("echo_pan", ec_pan, sp_ec_pan);
1318 store_float_sp("echo_volume", ec_volume, sp_ec_volume);
1320 store_id("speed", sp_speed.get_persistence_id());
1321 store_id("trigger", sp_trigger.get_persistence_id());
1322 store_id("spin", sp_spin.get_persistence_id());
1326 store_int("x_axis_mapping", x_par->get_persistence_id());
1330 store_int("y_axis_mapping", y_par->get_persistence_id());
1333 store_bool("audio_panel_hidden", audio_hidden);
1334 store_bool("control_panel_hidden", control_hidden);
1335 store_bool("main_panel_hidden", gui.main_panel->is_hidden());
1336 store_bool("trigger_panel_hidden", gui.trigger_panel->is_hidden());
1337 store_bool("lowpass_panel_hidden", gui.lp_panel->is_hidden());
1338 store_bool("echo_panel_hidden", gui.ec_panel->is_hidden());
1340 store_bool("mix_mute", mix_mute);
1341 store_bool("mix_solo", mix_solo);
1343 store_float("audio_x_zoom", gui_get_audio_x_zoom(this));
1345 tX_store("%s<fx>\n", indent);
1346 strcat(indent, "\t");
1348 for (list <vtt_fx *> :: iterator effect=fx_list.begin(); effect!=fx_list.end(); effect++) {
1349 (*effect)->save(rc, rz, indent);
1351 indent[strlen(indent)-1]=0;
1352 tX_store("%s</fx>\n", indent);
1354 tX_store("%s<stereo_fx>\n", indent);
1355 strcat(indent, "\t");
1357 for (list <vtt_fx_stereo_ladspa *> :: iterator effect=stereo_fx_list.begin(); effect!=stereo_fx_list.end(); effect++) {
1358 (*effect)->save(rc, rz, indent);
1360 indent[strlen(indent)-1]=0;
1361 tX_store("%s</stereo_fx>\n", indent);
1363 indent[strlen(indent)-1]=0;
1364 tX_store("%s</turntable>\n", indent);
1369 #define TX_XML_SETFILE_VERSION "1.0"
1371 int vtt_class :: save_all(FILE* rc, gzFile rz) {
1373 list <vtt_class *> :: iterator vtt;
1376 tX_seqpar :: create_persistence_ids();
1378 tX_store("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n");
1379 tX_store("<terminatorXset version=\"%s\">\n", TX_XML_SETFILE_VERSION);
1381 strcpy(indent, "\t");
1383 //store_int(vtt_amount); obsolete
1385 store_float_sp("master_volume", master_volume, sp_master_volume);
1386 store_float_sp("master_pitch", globals.pitch, sp_master_pitch);
1388 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++) {
1389 res+=(*vtt)->save(rc, rz, indent);
1392 sequencer.save(rc, rz, indent);
1394 tX_store("</terminatorXset>\n");
1399 int vtt_class :: load(xmlDocPtr doc, xmlNodePtr node) {
1409 char tmp_xml_buffer[4096];
1411 for (xmlNodePtr cur=node->xmlChildrenNode; cur != NULL; cur = cur->next) {
1412 if (cur->type == XML_ELEMENT_NODE) {
1415 restore_string_ac("name", buffer, set_name(buffer));
1416 restore_string("audiofile", filename);
1417 restore_bool("sync_master", is_sync_master);
1418 restore_bool("autotrigger", autotrigger);
1419 restore_bool_id("loop", loop, sp_loop, nop);
1420 restore_bool_id("sync_client", is_sync_client, sp_sync_client, set_sync_client(is_sync_client, sync_cycles));
1421 restore_int_id("sync_cycles", sync_cycles, sp_sync_cycles, set_sync_client(is_sync_client, sync_cycles));
1422 restore_float_id("volume", rel_volume, sp_volume, recalc_volume());
1423 restore_float_id("pitch", rel_pitch, sp_pitch, recalc_pitch());
1424 restore_bool_id("mute", mute, sp_mute, set_mute(mute));
1425 restore_float_id("pan", pan, sp_pan, set_pan(pan));
1427 restore_bool_id("lowpass_enable", lp_enable, sp_lp_enable, lp_set_enable(lp_enable));
1428 restore_float_id("lowpass_gain", lp_gain, sp_lp_gain, lp_set_gain(lp_gain));
1429 restore_float_id("lowpass_reso", lp_reso, sp_lp_reso, lp_set_reso(lp_reso));
1430 restore_float_id("lowpass_freq", lp_freq, sp_lp_freq, lp_set_freq(lp_freq));
1432 restore_bool_id("echo_enable", ec_enable, sp_ec_enable, ec_set_enable(ec_enable));
1433 restore_float_id("echo_length", ec_length, sp_ec_length, ec_set_length(ec_length));
1434 restore_float_id("echo_feedback", ec_feedback, sp_ec_feedback, ec_set_feedback(ec_feedback));
1435 restore_float_id("echo_pan", ec_pan, sp_ec_pan, ec_set_pan(ec_pan));
1436 restore_float_id("echo_volume", ec_volume, sp_ec_volume, ec_set_volume(ec_volume));
1438 restore_id("speed", sp_speed);
1439 restore_id("trigger", sp_trigger);
1440 restore_id("spin", sp_spin);
1442 restore_int("x_axis_mapping", xpar_id);
1443 restore_int("y_axis_mapping", ypar_id);
1445 restore_bool("mix_mute", mix_mute);
1446 restore_bool("mix_solo", mix_solo);
1448 restore_bool("audio_panel_hidden", audio_hidden);
1449 restore_bool("control_panel_hidden", control_hidden);
1450 restore_bool_ac("main_panel_hidden", hidden, gui.main_panel->hide(hidden));
1451 restore_bool_ac("trigger_panel_hidden", hidden, gui.trigger_panel->hide(hidden));
1452 restore_bool_ac("lowpass_panel_hidden", hidden, gui.lp_panel->hide(hidden));
1453 restore_bool_ac("echo_panel_hidden", hidden, gui.ec_panel->hide(hidden));
1454 restore_float_ac("audio_x_zoom", tmp, gui_set_audio_x_zoom(this,tmp));
1455 vg_adjust_zoom(gui.zoom, this);
1457 if ((xmlStrcmp(cur->name, (xmlChar *) "fx")==0) ||
1458 (xmlStrcmp(cur->name, (xmlChar *) "stereo_fx")==0)) {
1459 bool stereo=(xmlStrcmp(cur->name, (xmlChar *) "stereo_fx")==0);
1463 for (xmlNodePtr cur=fx->xmlChildrenNode; cur != NULL; cur = cur->next) {
1464 if (cur->type == XML_ELEMENT_NODE) {
1467 if (xmlStrcmp(cur->name, (xmlChar *) "cutoff")==0) {
1468 for (unsigned int t=0; t<fx_list.size(); t++) effect_down(lp_fx);
1470 } else if (xmlStrcmp(cur->name, (xmlChar *) "lowpass")==0) {
1471 for (unsigned int t=0; t<fx_list.size(); t++) effect_down(ec_fx);
1473 } else if (xmlStrcmp(cur->name, (xmlChar *) "ladspa_plugin")==0) {
1474 xmlNodePtr pluginNode=cur;
1478 for (xmlNodePtr cur=pluginNode->xmlChildrenNode; cur!=NULL; cur = cur->next) {
1480 if (cur->type == XML_ELEMENT_NODE) {
1483 restore_int("ladspa_id", ladspa_id);
1484 if (elementFound) break;
1488 if (ladspa_id!=-1) {
1489 LADSPA_Plugin *plugin=LADSPA_Plugin::getPluginByUniqueID(ladspa_id);
1490 if (!plugin) plugin=LADSPA_Stereo_Plugin::getPluginByUniqueID(ladspa_id);
1493 vtt_fx_ladspa *ladspa_effect=NULL;
1495 if (plugin->is_stereo()) {
1496 ladspa_effect=add_stereo_effect((LADSPA_Stereo_Plugin *) plugin);
1498 sprintf(buffer,"Trying to load mono plugin into stereo queue [%i].", ladspa_id);
1499 tx_note(buffer, true, GTK_WINDOW(gtk_widget_get_toplevel(ld_loaddlg)));
1502 ladspa_effect=add_effect(plugin);
1504 sprintf(buffer,"Trying to load stereo plugin into mono queue [%i].", ladspa_id);
1505 tx_note(buffer, true, GTK_WINDOW(gtk_widget_get_toplevel(ld_loaddlg)));
1509 ladspa_effect->load(doc, pluginNode);
1511 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);
1512 tx_note(buffer, true, GTK_WINDOW(gtk_widget_get_toplevel(ld_loaddlg)));
1515 tX_warning("ladspa_plugin section without a ladspa_id element.");
1519 tX_warning("unhandled element %s in fx section.", cur->name);
1526 tX_warning("unhandled element %s in turntable secion.", cur->name);
1538 set_x_input_parameter(tX_seqpar::get_sp_by_persistence_id(xpar_id));
1540 else set_x_input_parameter(NULL);
1543 set_y_input_parameter(tX_seqpar::get_sp_by_persistence_id(ypar_id));
1545 else set_y_input_parameter(NULL);
1547 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gui.mute), mix_mute);
1548 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gui.solo), mix_solo);
1553 void vtt_class :: delete_all()
1555 while (main_list.size()) {
1556 delete((*main_list.begin()));
1559 /* Take care of the master events.. */
1560 sequencer.delete_all_events(tX_sequencer::DELETE_ALL);
1562 /* Now reset master settings ot the default: */
1563 set_master_pitch(1.0);
1564 set_master_volume(1.0);
1566 sp_master_pitch.do_exec(1.0);
1567 sp_master_pitch.do_update_graphics();
1569 sp_master_volume.do_exec(1.0);
1570 sp_master_volume.do_update_graphics();
1572 /* Remove master MIDI mappings... */
1573 sp_master_pitch.bound_midi_event.type=tX_midievent::NONE;
1574 sp_master_volume.bound_midi_event.type=tX_midievent::NONE;
1579 int vtt_class :: load_all(xmlDocPtr doc, char *fname) {
1580 xmlNodePtr root=xmlDocGetRootElement(doc);
1588 tX_error("no root element? What kind of XML document is this?");
1592 if (xmlStrcmp(root->name, (const xmlChar *) "terminatorXset")) {
1593 tX_error("this is not a terminatorXset file.")
1597 if (xmlGetProp(root,(xmlChar *) "version")==NULL) {
1598 tX_error("the set file lacks a version attribute.");
1602 if (xmlStrcmp(xmlGetProp(root, (xmlChar *) "version"), (xmlChar *) TX_XML_SETFILE_VERSION)) {
1603 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);
1606 /* delete current tables... */
1611 /* counting turntables.. */
1612 for (xmlNodePtr cur=root->xmlChildrenNode; cur != NULL; cur = cur->next) {
1613 if (cur->type == XML_ELEMENT_NODE) {
1614 if (xmlStrcmp(cur->name, (xmlChar *) "turntable")==0) {
1620 tX_debug("Found %i turntables in set.", table_ctr);
1622 ld_create_loaddlg(TX_LOADDLG_MODE_MULTI, table_ctr);
1623 ld_set_setname(fname);
1626 for (xmlNodePtr cur=root->xmlChildrenNode; cur != NULL; cur = cur->next) {
1627 if (cur->type == XML_ELEMENT_NODE) {
1630 restore_float_id("master_volume", master_volume, sp_master_volume, set_master_volume(master_volume));
1631 restore_float_id("master_pitch", globals.pitch, sp_master_pitch, set_master_pitch(globals.pitch));
1633 if ((!elementFound) && (xmlStrcmp(cur->name, (xmlChar *) "turntable")==0)) {
1635 vtt_class *vtt=new vtt_class(1);
1636 vtt->load(doc, cur);
1638 if (strlen(vtt->filename)) {
1639 strcpy(fn_buff, vtt->filename);
1640 ld_set_filename(fn_buff);
1642 restmp=(int) vtt->load_file(fn_buff);
1646 gtk_box_pack_start(GTK_BOX(control_parent), vtt->gui.control_box, TRUE, TRUE, 0);
1647 gtk_box_pack_start(GTK_BOX(audio_parent), vtt->gui.audio_box, TRUE, TRUE, 0);
1648 if (vtt->audio_hidden) vtt->hide_audio(vtt->audio_hidden);
1649 if (vtt->control_hidden) vtt->hide_control(vtt->control_hidden);
\r
1651 if ((!elementFound) && (xmlStrcmp(cur->name, (xmlChar *) "sequencer")==0)) {
1653 sequencer.load(doc, cur);
1655 if (!elementFound) {
1656 tX_warning("unhandled element %s in setfile %s", cur->name, fname);
1661 sp_master_volume.do_update_graphics();
1662 sp_master_pitch.do_update_graphics();
1669 void add_vtt(GtkWidget *ctrl, GtkWidget *audio, char *fn)
1672 new_tt = new vtt_class(1);
1673 gtk_box_pack_start(GTK_BOX(ctrl), new_tt->gui.control_box, TRUE, TRUE, 0);
1674 gtk_box_pack_start(GTK_BOX(audio), new_tt->gui.audio_box, TRUE, TRUE, 0);
1675 if (fn) new_tt->load_file(fn);
1678 extern void vg_move_fx_panel_up(GtkWidget *wid, vtt_class *vtt, bool stereo);
1679 extern void vg_move_fx_panel_down(GtkWidget *wid, vtt_class *vtt, bool stereo);
1681 //#define debug_fx_stack(); for (i=list->begin(); i != list->end(); i++) puts((*i)->get_info_string());
1682 #define debug_fx_stack();
1684 void vtt_class :: effect_up(vtt_fx *effect)
1686 list <vtt_fx *> :: iterator i;
1687 list <vtt_fx *> :: iterator previous;
1688 list <vtt_fx *> *list;
1691 if (effect->is_stereo()) {
1692 list=(std::list <vtt_fx *> *) &stereo_fx_list;
1699 if ((*list->begin())==effect) return;
1701 for (previous=i=list->begin(); i != list->end(); i++) {
1702 if ((*i) == effect) {
1710 pthread_mutex_lock(&render_lock);
1711 list->remove(effect);
1712 list->insert(previous, effect);
1713 pthread_mutex_unlock(&render_lock);
1715 vg_move_fx_panel_up(effect->get_panel_widget(), this, effect->is_stereo());
1721 void vtt_class :: effect_down(vtt_fx *effect)
1723 list <vtt_fx *> :: iterator i;
1724 list <vtt_fx *> *list;
1727 if (effect->is_stereo()) {
1728 list=(std::list <vtt_fx *> *) &stereo_fx_list;
1735 for (i=list->begin(); i != list->end(); i++) {
1736 if ((*i) == effect) {
1742 if ((ok) && (i!=list->end())) {
1744 if (i==list->end()) return;
1747 pthread_mutex_lock(&render_lock);
1748 list->remove(effect);
1750 list->insert(i, effect);
1751 vg_move_fx_panel_down(effect->get_panel_widget(), this, effect->is_stereo());
1752 pthread_mutex_unlock(&render_lock);
1758 void vtt_class :: effect_remove(vtt_fx_ladspa *effect)
1760 pthread_mutex_lock(&render_lock);
1761 if (effect->is_stereo()) {
1762 stereo_fx_list.remove((vtt_fx_stereo_ladspa *) effect);
1764 fx_list.remove(effect);
1766 pthread_mutex_unlock(&render_lock);
1771 extern void gui_hide_control_panel(vtt_class *vtt, bool hide);
1772 extern void gui_hide_audio_panel(vtt_class *vtt, bool hide);
1774 void vtt_class :: hide_audio(bool hide) {
1776 gui_hide_audio_panel(this, hide);
1779 void vtt_class :: hide_control(bool hide) {
1780 control_hidden=hide;
1781 gui_hide_control_panel(this, hide);
1784 void vtt_class :: set_sample_rate(int samplerate) {
1785 list <vtt_class *> :: iterator vtt;
1786 double sr=(double) samplerate;
1788 last_sample_rate=samplerate;
1790 for (vtt=main_list.begin(); vtt!=main_list.end() ; vtt++) {
1791 if ((*vtt)->audiofile) {
1792 double file_rate=(*vtt)->audiofile->get_sample_rate();
1793 (*vtt)->audiofile_pitch_correction=file_rate/sr;
1795 (*vtt)->audiofile_pitch_correction=1.0;
1797 (*vtt)->recalc_pitch();
1800 int no_samples=(int) (sr*0.001); // Forcing 1 ms blocksize
1802 set_mix_buffer_size(no_samples);
1805 void vtt_class :: adjust_to_master_pitch(int master_cycles, int cycles, bool create_event) {
1806 if (!sync_master) return;
1807 if (this==sync_master) return;
1808 if (!sync_master->audiofile) return;
1809 if (!audiofile) return;
1811 double master_time=((double) master_cycles)/sync_master->rel_pitch*sync_master->audiofile->get_no_samples()/((double) sync_master->audiofile->get_sample_rate());
1812 double my_rel_pitch=((audiofile->get_no_samples()/((double) audiofile->get_sample_rate()))*((double) cycles))/master_time;
1815 sp_pitch.do_exec(my_rel_pitch);
1816 sp_pitch.record_value(my_rel_pitch);
1818 sp_pitch.do_exec(my_rel_pitch);
1821 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());
1823 sp_pitch.update_graphics();