2 terminatorX - realtime audio scratching software
3 Copyright (C) 1999-2002 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"
47 #define tX_freemem(ptr, varname, comment); fprintf(stderr, "** free() [%s] at %08x. %s.\n", varname, ptr, comment); free(ptr);
48 #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);
50 #define tX_freemem(ptr, varname, comment); free(ptr);
51 #define tX_malloc(ptr, varname, comment, size, type); ptr=type malloc(size);
54 #include "tX_loaddlg.h"
56 #define USE_PREFETCH 1
59 #define my_prefetch(base, index); __asm__ __volatile__ ("prefetch index(%0)\n" : : "r" (base));
60 #define my_prefetchw(base, index); __asm__ __volatile__ ("prefetchw index(%0)\n" : : "r" (base));
62 #define my_prefetch(base, index); /* NOP */;
63 #define my_prefetchw(base, index); /* NOP */;
66 extern void build_vtt_gui(vtt_class *);
67 extern void gui_set_name(vtt_class *vtt, char *newname);
68 extern void gui_set_filename(vtt_class *vtt, char *newname);
69 extern void delete_gui(vtt_class *vtt);
70 extern void gui_update_display(vtt_class *vtt);
71 extern void gui_clear_master_button(vtt_class *vtt);
72 extern void cleanup_vtt(vtt_class *vtt);
73 extern int vg_get_current_page(vtt_class *vtt);
74 extern f_prec gui_get_audio_x_zoom(vtt_class *vtt);
75 extern void gui_set_audio_x_zoom(vtt_class *vtt, f_prec);
78 int vtt_class::vtt_amount=0;
79 list <vtt_class *> vtt_class::main_list;
80 list <vtt_class *> vtt_class::render_list;
81 int16_t* vtt_class::mix_out_buffer=NULL;
82 f_prec * vtt_class::mix_buffer=NULL;
83 f_prec * vtt_class::mix_buffer_end=NULL;
84 int vtt_class::solo_ctr=0;
86 int vtt_class::samples_in_mix_buffer=0;
87 pthread_mutex_t vtt_class::render_lock=PTHREAD_MUTEX_INITIALIZER;
88 f_prec vtt_class::master_volume=1.0;
89 f_prec vtt_class::res_master_volume=1.0;
90 f_prec vtt_class::saturate_fac=0.1;
91 int vtt_class::do_saturate=0;
92 vtt_class * vtt_class::sync_master=NULL;
93 int vtt_class::master_triggered=0;
94 int vtt_class::master_triggered_at=0;
95 vtt_class * vtt_class::focused_vtt=NULL;
96 f_prec vtt_class::mix_max_l=0;
97 f_prec vtt_class::mix_max_r=0;
98 f_prec vtt_class::vol_channel_adjust=1.0;
100 #define GAIN_AUTO_ADJUST 0.8
102 vtt_class :: vtt_class (int do_create_gui)
105 sprintf (name, "Turntable %i", vtt_amount);
106 strcpy(filename, "NONE");
126 lp_setup(lp_gain, lp_reso, lp_freq);
137 main_list.push_back(this);
139 /* "connecting" the seq-parameters */
141 sp_speed.set_vtt((void *) this);
142 sp_volume.set_vtt((void *) this);
143 sp_pitch.set_vtt((void *) this);
144 sp_pan.set_vtt((void *) this);
145 sp_trigger.set_vtt((void *) this);
146 sp_loop.set_vtt((void *) this);
147 sp_sync_client.set_vtt((void *) this);
148 sp_sync_cycles.set_vtt((void *) this);
149 sp_lp_enable.set_vtt((void *) this);
150 sp_lp_gain.set_vtt((void *) this);
151 sp_lp_reso.set_vtt((void *) this);
152 sp_lp_freq.set_vtt((void *) this);
153 sp_ec_enable.set_vtt((void *) this);
154 sp_ec_length.set_vtt((void *) this);
155 sp_ec_pan.set_vtt((void *) this);
156 sp_ec_volume.set_vtt((void *) this);
157 sp_ec_feedback.set_vtt((void *) this);
158 sp_mute.set_vtt((void *) this);
159 sp_spin.set_vtt((void *) this);
164 lp_fx=new vtt_fx_lp();
165 lp_fx->set_vtt((void *) this);
166 fx_list.push_back(lp_fx);
168 ec_fx=new vtt_fx_ec();
169 ec_fx->set_vtt((void *) this);
170 fx_list.push_back(ec_fx);
175 lp_fx->set_panel_widget(gui.lp_panel->get_widget());
176 ec_fx->set_panel_widget(gui.ec_panel->get_widget());
181 set_master_volume(globals.volume);
182 set_output_buffer_size(samples_in_mix_buffer/2);
185 audiofile_pitch_correction=0;
192 control_hidden=false;
\r
195 vtt_class :: ~vtt_class()
200 main_list.remove(this);
201 if (audiofile) delete audiofile;
202 //if (buffer) free(buffer);
203 if (output_buffer) tX_freemem(output_buffer, "output_buffer", "vtt Destructor");
206 while (fx_list.size())
208 effect=(*fx_list.begin());
209 fx_list.remove(effect);
216 void vtt_class :: set_name(char *newname)
218 strcpy(name, newname);
219 gui_set_name(this, name);
222 tX_audio_error vtt_class :: load_file(char *fname)
225 int was_playing=is_playing;
227 if (is_playing) stop();
229 if (audiofile) delete(audiofile);
236 audiofile=new tx_audiofile();
237 res=audiofile->load(fname);
239 if (res==TX_AUDIO_SUCCESS) {
240 buffer=audiofile->get_buffer();
241 double file_rate=audiofile->get_sample_rate();
242 audiofile_pitch_correction=file_rate/44100.0;
244 samples_in_buffer=audiofile->get_no_samples();
245 maxpos=audiofile->get_no_samples();
246 strcpy(filename, fname);
247 if (was_playing) trigger();
248 // printf("Successfully loaded %s, %08x, %i\n", fname, buffer, samples_in_buffer);
253 gui_update_display(this);
255 ec_set_length(ec_length);
260 int vtt_class :: set_output_buffer_size(int newsize)
262 list <vtt_fx *> :: iterator effect;
264 if (ec_output_buffer) tX_freemem(ec_output_buffer, "ec_output_buffer", "vtt set_output_buffer_size()");
265 tX_malloc(ec_output_buffer, "ec_output_buffer", "vtt set_output_buffer_size()", sizeof(float)*newsize, (float *));
267 if (output_buffer) tX_freemem(output_buffer, "output_buffer", "vtt set_output_buffer_size()");
268 tX_malloc(output_buffer, "output_buffer", "vtt set_output_buffer_size()", sizeof(float)*newsize, (float *));
270 end_of_outputbuffer = output_buffer + newsize; //size_t(sizeof(float)*(newsize));
272 samples_in_outputbuffer=newsize;
273 inv_samples_in_outputbuffer=1.0/samples_in_outputbuffer;
275 for (effect=fx_list.begin(); effect != fx_list.end(); effect++)
277 (*effect)->reconnect_buffer();
280 if (output_buffer) return(0);
284 void vtt_class :: set_volume(f_prec newvol)
290 void vtt_class :: recalc_volume()
292 res_volume=rel_volume*res_master_volume;
293 f_prec ec_res_volume=res_volume*ec_volume;
297 res_volume_left=(1.0-pan)*res_volume;
298 res_volume_right=res_volume;
302 res_volume_left=res_volume;
303 res_volume_right=(1.0+pan)*res_volume;
307 res_volume_left=res_volume_right=res_volume;
312 ec_volume_left=(1.0-ec_pan)*ec_res_volume;
313 ec_volume_right=ec_res_volume;
317 ec_volume_left=ec_res_volume;
318 ec_volume_right=(1.0+ec_pan)*ec_res_volume;
322 ec_volume_left=ec_volume_right=ec_res_volume;
324 // printf("vtt_volume: %f, %f, l: %f, r: %f\n", rel_volume, res_volume, res_volume_left, res_volume_right);
327 mm_res_volume.s[0]=mm_res_volume.s[1]=res_volume;
331 void vtt_class :: set_pan(f_prec newpan)
337 void vtt_class :: set_pitch(f_prec newpitch)
340 res_pitch=globals.pitch*rel_pitch;
342 ec_set_length(ec_length);
345 void vtt_class :: recalc_pitch()
347 res_pitch=globals.pitch*rel_pitch;
348 res_pitch*=audiofile_pitch_correction;
350 ec_set_length(ec_length);
353 void vtt_class :: set_autotrigger(int newstate)
355 autotrigger=newstate;
358 void vtt_class :: set_loop(int newstate)
363 void vtt_class :: set_mute(int newstate)
369 void vtt_class :: set_mix_mute(int newstate)
375 void vtt_class :: set_mix_solo(int newstate)
377 if (mix_solo && !newstate)
383 else if (!mix_solo && newstate)
392 list <vtt_class *> :: iterator vtt;
394 for (vtt=main_list.begin(); vtt!=main_list.end() ; vtt++)
400 void vtt_class :: lp_set_enable (int newstate)
406 void vtt_class :: lp_reset()
411 void vtt_class :: lp_set_gain (f_prec gain)
414 lp_resgain=lp_gain*lp_autogain;
417 void vtt_class :: lp_set_reso(f_prec reso)
421 lp_b=reso*(1.0+(1.0/lp_a));
422 lp_autogain=1.0-reso*GAIN_AUTO_ADJUST;
423 lp_resgain=lp_gain*lp_autogain;
426 void vtt_class :: lp_set_freq(f_prec freq)
431 lp_b=lp_reso*(1.0+(1.0/lp_a));
434 void vtt_class :: lp_setup(f_prec gain, f_prec reso, f_prec freq)
440 lp_b=reso*(1.0+(1.0/lp_a));
442 lp_autogain=1.0-reso*GAIN_AUTO_ADJUST;
443 lp_resgain=lp_gain*lp_autogain;
446 void vtt_class :: ec_set_enable(int newstate)
453 void vtt_class :: ec_set_pan(f_prec pan)
460 /* Max length is 1.0 */
462 void vtt_class :: ec_set_length(f_prec length)
469 ec_res_length=length*samples_in_buffer;
473 ec_res_length=length*samples_in_buffer/res_pitch;
476 if (ec_res_length<0) ec_res_length*=-1;
478 if (ec_res_length>=EC_MAX_BUFFER)
480 ec_res_length=EC_MAX_BUFFER*length;
483 delay=(int )floor(ec_res_length);
485 ec_delay=&ec_buffer[delay];
488 void vtt_class :: ec_set_feedback(f_prec feedback)
490 ec_feedback=feedback;
494 void vtt_class :: ec_set_volume(f_prec volume)
500 void vtt_class :: ec_clear_buffer()
504 for (ptr=ec_buffer; ptr<=ec_delay; ptr++)
511 void vtt_class :: render()
513 list <vtt_fx *> :: iterator effect;
520 if (sense_cycles==0) sp_speed.receive_input_value(0);
525 for (effect=fx_list.begin(); effect != fx_list.end(); effect++)
527 if ((*effect)->isEnabled()) (*effect)->run();
531 extern void vg_create_fx_gui(vtt_class *vtt, vtt_fx_ladspa *effect, LADSPA_Plugin *plugin);
533 vtt_fx_ladspa * vtt_class :: add_effect (LADSPA_Plugin *plugin)
535 vtt_fx_ladspa *new_effect;
537 new_effect = new vtt_fx_ladspa (plugin, this);
538 pthread_mutex_lock(&render_lock);
539 fx_list.push_back(new_effect);
540 if (is_playing) new_effect->activate();
541 pthread_mutex_unlock(&render_lock);
542 vg_create_fx_gui(this, new_effect, plugin);
547 void vtt_class :: calc_speed()
549 do_mute=fade_out=fade_in=0;
551 if (speed != speed_target)
554 speed_step=speed_target-speed_real;
558 if (speed_target != speed_real)
560 speed_real+=speed_step;
561 if ((speed_step<0) && (speed_real<speed_target)) speed_real=speed_target;
563 if ((speed_step>0) && (speed_real>speed_target)) speed_real=speed_target;
568 if ((speed_last==0) && (speed_real !=0))
576 if ((speed_last!=0) && (speed_real==0))
583 speed_last = speed_real;
585 if (res_mute != res_mute_old)
589 fade_out=1; fade_in=0;
594 fade_in=1; fade_out=0;
597 res_mute_old=res_mute;
601 if (res_mute) do_mute=1;
605 void vtt_class :: render_scratch()
626 for (sample =0,out=output_buffer, fade_vol=0.0; sample < samples_in_outputbuffer;sample++, out++, fade_vol+=inv_samples_in_outputbuffer)
628 if ((speed_real!=0) || (fade_out))
643 master_triggered_at=sample;
663 master_triggered_at=sample;
673 pos_a_f=floor(pos_f);
674 pos_i=(unsigned int) pos_a_f;
676 amount_b=pos_f-pos_a_f;
677 amount_a=1.0-amount_b;
686 sample_a=(f_prec) *ptr;
688 if (pos_i == samples_in_buffer)
695 sample_b=(f_prec) *ptr;
698 sample_res=(sample_a*amount_a)+(sample_b*amount_b);
702 sample_res*=fade_vol;
707 sample_res*=1.0-fade_vol;
720 void vtt_class :: forward_turntable()
731 if ((speed_real==0) && (!fade_out)) return;
734 /* following code is problematic as adding speed_real*n is
735 different from adding speed_real n times to pos_f.
737 well it speeds things up quite a bit and double precision
738 seems to do a satisfying job.
740 #define pos_f_test to prove that.
743 pos_f_tmp=pos_f+speed_real*samples_in_outputbuffer;
745 if ((pos_f_tmp > 0) && (pos_f_tmp < maxpos))
755 /* now the slow way ;) */
757 for (sample =0; sample < samples_in_outputbuffer; sample++)
771 master_triggered_at=sample;
791 master_triggered_at=sample;
805 diff=pos_f_tmp-pos_f;
806 if (diff!=0) printf("fast: %f, slow: %f, diff: %f, tt: %s\n", pos_f_tmp, pos_f, diff, name);
812 The following lowpass filter is based on some sample code by
813 Paul Kellett <paul.kellett@maxim.abel.co.uk>
816 void vtt_class :: render_lp()
820 for (sample = output_buffer; sample<end_of_outputbuffer; sample++)
822 lp_buf0 = lp_a * lp_buf0 + lp_freq * ((*sample)*lp_resgain + lp_b * (lp_buf0 - lp_buf1));
823 lp_buf1 = lp_a * lp_buf1 + lp_freq * lp_buf0;
829 void vtt_class :: render_ec()
835 for (i=0, sample = output_buffer, ec_sample=ec_output_buffer; i<samples_in_outputbuffer; i++, ec_sample++,sample++, ec_ptr++)
837 if (ec_ptr>ec_delay) ec_ptr=ec_buffer;
838 *ec_sample=(*ec_ptr) *ec_feedback;
839 *ec_ptr=*sample+*ec_sample;
843 int vtt_class :: set_mix_buffer_size(int no_samples)
845 list <vtt_class *> :: iterator vtt;
848 // printf("vtt_class::set_mix_buffer_size(), mix_buffer: %12x, mix_out: %12x, samples: %i\n", mix_buffer, mix_out_buffer, no_samples);
850 if (mix_buffer) tX_freemem(mix_buffer, "mix_buffer", "vtt set_mix_buffer_size()");
851 samples_in_mix_buffer=no_samples*2;
853 tX_malloc(mix_buffer, "mix_buffer", "vtt set_mix_buffer_size()", sizeof(float)*samples_in_mix_buffer, (float *));
854 mix_buffer_end=mix_buffer+samples_in_mix_buffer;
856 // printf("mix_buffer: %12x\n", mix_buffer);
857 // printf("mix_samples: %i, out_samples: %i", samples_in_mix_buffer, no_samples);
859 if (mix_out_buffer) tX_freemem(mix_out_buffer, "mix_out_buffer", "vtt set_mix_buffer_size()");
860 tX_malloc(mix_out_buffer, "mix_out_buffer", "vtt set_mix_buffer_size()", sizeof(int16_t)*samples_in_mix_buffer + 4, (int16_t *));
862 // printf("mix_out_buffer: %12x\n", mix_out_buffer);
864 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
866 res|=(*vtt)->set_output_buffer_size(no_samples);
869 if ((!mix_buffer) || (!mix_out_buffer) || res) return(1);
873 int16_t * vtt_class :: render_all_turntables()
875 list <vtt_class *> :: iterator vtt, next;
896 #ifndef OVERRIDE_MOVQ_AUTODETECT
898 #define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
899 #endif /* GCC_VERSION */
901 #if (GCC_VERSION < 2096)
902 #warning "*************************"
903 #warning "* gcc < 2.96 *"
904 #warning "* assuming working movq *"
905 #warning "*************************"
906 #undef GCC_MOVQ_BUG_WORKAROUND
908 #warning "*************************"
909 #warning "* gcc >= 2.96 *"
910 #warning "* using movq-workaround *"
911 #warning "*************************"
912 #define GCC_MOVQ_BUG_WORKAROUND 1
913 #endif /* GCC < 2.96 */
914 #endif /* OVERRIDE MOVQ AUTODETECVT */
916 #ifdef GCC_MOVQ_BUG_WORKAROUND
917 /* REQUIRED DUE TO GCC BUG (2.96-3.0.2) */
918 mmx_t *mm_src1_ptr=&mm_src1;
919 mmx_t *mm_src2_ptr=&mm_src2;
920 mmx_t *mm_volume_ptr=&mm_volume;
921 mmx_t *mm_max_ptr=&mm_max;
922 mmx_t *mm_min_ptr=&mm_min;
924 #define MM_VAR_ACC(var) (* var ## _ptr)
925 #define MM_VAR_MOVQ(var) * var ## _ptr
927 #define MM_VAR_ACC(var) var
928 #define MM_VAR_MOVQ(var) var
930 int32_t *temp_int=&mm_max.d[1];
934 pthread_mutex_lock(&render_lock);
936 if (render_list.size()==0)
938 for (sample=0; sample<samples_in_mix_buffer; sample++)
940 mix_out_buffer[sample]=0;
945 vtt=render_list.begin();
947 max=(*vtt)->max_value;
951 for (sample=0, mix_sample=0; sample<(*vtt)->samples_in_outputbuffer; sample++)
953 temp=(*vtt)->output_buffer[sample];
954 mix_buffer[mix_sample]=temp*(*vtt)->res_volume_left;
956 mix_buffer[mix_sample]=temp*(*vtt)->res_volume_right;
959 if (temp>max) max=temp;
960 else if (temp<min) min=temp;
963 MM_VAR_ACC(mm_volume).s[0]=(*vtt)->res_volume_left;
964 MM_VAR_ACC(mm_volume).s[1]=(*vtt)->res_volume_right;
966 MM_VAR_ACC(mm_max).s[1]=MM_VAR_ACC(mm_max).s[0]=max;
967 MM_VAR_ACC(mm_min).s[1]=MM_VAR_ACC(mm_min).s[0]=min;
969 movq_m2r(MM_VAR_MOVQ(mm_max), mm1);
970 movq_m2r(MM_VAR_MOVQ(mm_min), mm2);
972 movq_m2r(MM_VAR_MOVQ(mm_volume), mm0);
974 mix=(mmx_t*)mix_buffer;
976 for (f_prec* src=(*vtt)->output_buffer; mix < (mmx_t*) mix_buffer_end;)
979 MM_VAR_ACC(mm_src1).s[0]=*src;
980 MM_VAR_ACC(mm_src1).s[1]=*src;
982 /* sample * l/r volume */
983 movq_m2r(MM_VAR_MOVQ(mm_src1), mm3);
989 MM_VAR_ACC(mm_src2).s[0]=*src;
990 MM_VAR_ACC(mm_src2).s[1]=*src;
992 /* sample * l/r volume */
993 movq_m2r(MM_VAR_MOVQ(mm_src2), mm3);
997 /* calculating min/max */
998 MM_VAR_ACC(mm_src1).s[1]=MM_VAR_ACC(mm_src2).s[0];
999 movq_m2r(mm_src1, mm3);
1000 pfmax_r2r(mm3, mm1);
1001 pfmin_r2r(mm3, mm2);
1006 movq_r2m(mm1, MM_VAR_MOVQ(mm_max));
1007 movq_r2m(mm2, MM_VAR_MOVQ(mm_min));
1011 if (MM_VAR_ACC(mm_max).s[0]>MM_VAR_ACC(mm_max).s[1]) max=MM_VAR_ACC(mm_max).s[0]; else max=MM_VAR_ACC(mm_max).s[1];
1012 if (MM_VAR_ACC(mm_min).s[0]<MM_VAR_ACC(mm_min).s[0]) min=MM_VAR_ACC(mm_min).s[0]; else min=MM_VAR_ACC(mm_min).s[1];
1016 if (min>max) (*vtt)->max_value=min; else (*vtt)->max_value=max;
1018 if ((*vtt)->ec_enable)
1021 for (sample=0, mix_sample=0; sample<(*vtt)->samples_in_outputbuffer; sample++)
1023 temp=(*vtt)->ec_output_buffer[sample];
1025 mix_buffer[mix_sample]+=temp*(*vtt)->ec_volume_left;
1027 mix_buffer[mix_sample]+=temp*(*vtt)->ec_volume_right;
1031 MM_VAR_ACC(mm_volume).s[0]=(*vtt)->ec_volume_left;
1032 MM_VAR_ACC(mm_volume).s[1]=(*vtt)->ec_volume_right;
1034 movq_m2r(MM_VAR_MOVQ(mm_volume), mm0);
1035 mix =(mmx_t*)mix_buffer;
1037 for (f_prec* src=(*vtt)->ec_output_buffer; mix < (mmx_t*) mix_buffer_end; src++, mix++)
1040 MM_VAR_ACC(mm_src1).s[0]=*src;
1041 MM_VAR_ACC(mm_src1).s[1]=*src;
1043 /* sample * l/r volume */
1044 movq_m2r(MM_VAR_MOVQ(mm_src1), mm3);
1045 pfmul_r2r(mm0, mm3);
1047 /* accumulating complete mix */
1048 movq_m2r(*mix, mm4);
1049 pfadd_r2r(mm4, mm3);
1050 movq_r2m(mm3, *mix);
1056 if (master_triggered)
1058 pthread_mutex_unlock(&render_lock);
1059 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
1061 if ((*vtt)->is_sync_client)
1063 if ((*vtt)->sync_countdown)
1065 (*vtt)->sync_countdown--;
1069 (*vtt)->sync_countdown=(*vtt)->sync_cycles;
1074 pthread_mutex_lock(&render_lock);
1077 vtt=render_list.begin();
1078 for (vtt++; vtt!=render_list.end(); vtt++)
1081 max=(*vtt)->max_value;
1085 for (sample=0, mix_sample=0; sample<(*vtt)->samples_in_outputbuffer; sample++)
1087 temp=(*vtt)->output_buffer[sample];
1088 mix_buffer[mix_sample]+=temp*(*vtt)->res_volume_left;
1090 mix_buffer[mix_sample]+=temp*(*vtt)->res_volume_right;
1093 if (temp>max) max=temp;
1094 else if (temp<min) min=temp;
1097 MM_VAR_ACC(mm_volume).s[0]=(*vtt)->res_volume_left;
1098 MM_VAR_ACC(mm_volume).s[1]=(*vtt)->res_volume_right;
1100 MM_VAR_ACC(mm_max).s[1]=MM_VAR_ACC(mm_max).s[0]=max;
1101 MM_VAR_ACC(mm_min).s[1]=MM_VAR_ACC(mm_min).s[0]=min;
1103 movq_m2r(MM_VAR_MOVQ(mm_max), mm1);
1104 movq_m2r(MM_VAR_MOVQ(mm_min), mm2);
1106 movq_m2r(MM_VAR_MOVQ(mm_volume), mm0);
1107 mix=(mmx_t*)mix_buffer;
1109 for (f_prec* src=(*vtt)->output_buffer; mix < (mmx_t*) mix_buffer_end;)
1112 MM_VAR_ACC(mm_src1).s[0]=*src;
1113 MM_VAR_ACC(mm_src1).s[1]=*src;
1115 /* sample * l/r volume */
1116 movq_m2r(MM_VAR_MOVQ(mm_src1), mm3);
1117 pfmul_r2r(mm0, mm3);
1119 /* accumulating complete mix */
1120 movq_m2r(*mix, mm4);
1121 pfadd_r2r(mm4, mm3);
1122 movq_r2m(mm3, *mix);
1126 MM_VAR_ACC(mm_src2).s[0]=*src;
1127 MM_VAR_ACC(mm_src2).s[1]=*src;
1129 /* sample * l/r volume */
1130 movq_m2r(MM_VAR_MOVQ(mm_src2), mm3);
1131 pfmul_r2r(mm0, mm3);
1133 /* accumulating complete mix */
1134 movq_m2r(*mix, mm4);
1135 pfadd_r2r(mm4, mm3);
1136 movq_r2m(mm3, *mix);
1138 /* calculating min/max */
1139 MM_VAR_ACC(mm_src1).s[1]=MM_VAR_ACC(mm_src2).s[0];
1140 movq_m2r(MM_VAR_MOVQ(mm_src1), mm3);
1141 pfmax_r2r(mm3, mm1);
1142 pfmin_r2r(mm3, mm2);
1147 movq_r2m(mm1, MM_VAR_MOVQ(mm_max));
1148 movq_r2m(mm2, MM_VAR_MOVQ(mm_min));
1152 if (MM_VAR_ACC(mm_max).s[0]>MM_VAR_ACC(mm_max).s[1]) max=MM_VAR_ACC(mm_max).s[0]; else max=MM_VAR_ACC(mm_max).s[1];
1153 if (MM_VAR_ACC(mm_min).s[0]<MM_VAR_ACC(mm_min).s[0]) min=MM_VAR_ACC(mm_min).s[0]; else min=MM_VAR_ACC(mm_min).s[1];
1157 if (min>max) (*vtt)->max_value=min; else (*vtt)->max_value=max;
1159 if ((*vtt)->ec_enable)
1162 for (sample=0, mix_sample=0; sample<(*vtt)->samples_in_outputbuffer; sample++)
1164 temp=(*vtt)->ec_output_buffer[sample];
1166 mix_buffer[mix_sample]+=temp*(*vtt)->ec_volume_left;
1168 mix_buffer[mix_sample]+=temp*(*vtt)->ec_volume_right;
1172 MM_VAR_ACC(mm_volume).s[0]=(*vtt)->ec_volume_left;
1173 MM_VAR_ACC(mm_volume).s[1]=(*vtt)->ec_volume_right;
1175 movq_m2r(MM_VAR_MOVQ(mm_volume), mm0);
1176 mix =(mmx_t*)mix_buffer;
1178 for (f_prec* src=(*vtt)->ec_output_buffer; mix < (mmx_t*) mix_buffer_end; src++, mix++)
1181 MM_VAR_ACC(mm_src1).s[0]=*src;
1182 MM_VAR_ACC(mm_src1).s[1]=*src;
1184 /* sample * l/r volume */
1185 movq_m2r(MM_VAR_MOVQ(mm_src1), mm3);
1186 pfmul_r2r(mm0, mm3);
1188 /* accumulating complete mix */
1189 movq_m2r(*mix, mm4);
1190 pfadd_r2r(mm4, mm3);
1191 movq_r2m(mm3, *mix);
1204 for (sample=0; sample<samples_in_mix_buffer; sample+=2)
1206 temp=mix_buffer[sample];
1207 mix_out_buffer[sample]=(int16_t) temp;
1209 if (temp>max) max=temp;
1210 else if (temp<min) min=temp;
1214 if (min>max) mix_max_l=min; else mix_max_l=max;
1221 for (sample=1; sample<samples_in_mix_buffer; sample+=2)
1223 temp=mix_buffer[sample];
1224 mix_out_buffer[sample]=(int16_t) temp;
1226 if (temp>max) max=temp;
1227 else if (temp<min) min=temp;
1231 if (min>max) mix_max_r=min; else mix_max_r=max;
1236 vtt=render_list.begin();
1237 while (vtt!=render_list.end())
1242 if ((*vtt)->want_stop) (*vtt)->stop_nolock();
1245 pthread_mutex_unlock(&render_lock);
1247 return(mix_out_buffer);
1250 void vtt_class :: forward_all_turntables()
1252 list <vtt_class *> :: iterator vtt, next;
1254 if (render_list.size()>0)
1256 vtt=render_list.begin();
1257 (*vtt)->forward_turntable();
1259 if (master_triggered)
1261 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
1263 if ((*vtt)->is_sync_client)
1265 if ((*vtt)->sync_countdown)
1267 (*vtt)->sync_countdown--;
1271 (*vtt)->sync_countdown=(*vtt)->sync_cycles;
1278 vtt=render_list.begin();
1279 for (vtt++; vtt!=render_list.end(); vtt++)
1281 (*vtt)->forward_turntable();
1286 vtt=render_list.begin();
1287 while (vtt!=render_list.end())
1292 if ((*vtt)->want_stop) (*vtt)->stop_nolock();
1298 int vtt_class :: trigger()
1300 list <vtt_fx *> :: iterator effect;
1302 if (!buffer) return (1);
1304 if (!is_playing) pthread_mutex_lock(&render_lock);
1306 if (res_pitch>=0) pos_f=0;
1310 speed_real=res_pitch;
1311 speed_target=res_pitch;
1314 /* activating plugins */
1315 for (effect=fx_list.begin(); effect != fx_list.end(); effect++)
1317 (*effect)->activate();
1328 master_triggered_at=0;
1337 render_list.push_front(this);
1341 render_list.push_back(this);
1343 pthread_mutex_unlock(&render_lock);
1348 int vtt_class :: stop_nolock()
1350 list <vtt_fx *> :: iterator effect;
1354 pthread_mutex_unlock(&render_lock);
1357 render_list.remove(this);
1368 /* deactivating plugins */
1369 for (effect=fx_list.begin(); effect != fx_list.end(); effect++)
1371 (*effect)->deactivate();
1377 int vtt_class :: stop()
1381 pthread_mutex_lock(&render_lock);
1385 pthread_mutex_unlock(&render_lock);
1390 void vtt_class :: set_sync_master(int master)
1394 if (sync_master) sync_master->set_sync_master(0);
1400 if (sync_master==this) sync_master=0;
1402 gui_clear_master_button(this);
1406 void vtt_class :: set_sync_client(int slave, int cycles)
1408 is_sync_client=slave;
1410 // sync_countdown=cycles;
1414 void vtt_class :: set_sync_client_ug(int slave, int cycles)
1416 set_sync_client(slave, cycles);
1419 void vtt_class :: set_master_volume(f_prec new_volume)
1421 list <vtt_class *> :: iterator vtt;
1423 master_volume=new_volume;
1424 globals.volume=new_volume;
1426 if (main_list.size()>0)
1428 vol_channel_adjust=sqrt((f_prec) main_list.size());
1429 res_master_volume=master_volume/vol_channel_adjust;
1432 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
1434 (*vtt)->recalc_volume();
1438 void vtt_class :: set_master_pitch(f_prec new_pitch)
1440 list <vtt_class *> :: iterator vtt;
1442 globals.pitch=new_pitch;
1443 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++)
1445 (*vtt)->recalc_pitch();
1449 void vtt_class :: enable_saturate (int newstate)
1451 do_saturate=newstate;
1454 void vtt_class :: focus_no(int no)
1456 list <vtt_class *> :: iterator vtt;
1459 for (i=0, vtt=main_list.begin(); vtt!=main_list.end(); vtt++, i++)
1468 void vtt_class :: focus_next()
1470 list <vtt_class *> :: iterator vtt;
1474 if (main_list.size())
1476 focused_vtt=(*main_list.begin());
1481 for (vtt=main_list.begin(); vtt!=main_list.end() ; vtt++) {
1482 if ((*vtt)==focused_vtt) {
1483 /* Ok, we found ourselves.. */
1486 while ((vtt!=main_list.end()) && ((*vtt)->audio_hidden) ) {
1490 if (vtt==main_list.end()) {
1491 /* No other "focusable" after this vtt so we're looking for the next */
1493 for (vtt=main_list.begin(); vtt!=main_list.end() ; vtt++) {
1494 if (! (*vtt)->audio_hidden) {
1499 /* When we get here there's no "focusable" vtt at all... damn */
1509 focused_vtt=(*main_list.begin());
1512 void vtt_class :: set_scratch(int newstate)
1516 sp_spin.receive_input_value(0);
1518 sense_cycles=globals.sense_cycles;
1522 sp_spin.receive_input_value(1);
1528 void vtt_class :: unfocus()
1533 void vtt_class :: set_x_input_parameter(tX_seqpar *sp)
1538 void vtt_class :: set_y_input_parameter(tX_seqpar *sp)
1543 void vtt_class :: xy_input(f_prec x_value, f_prec y_value)
1545 if (x_par) x_par->handle_mouse_input(x_value*globals.mouse_speed);
1546 if (y_par) y_par->handle_mouse_input(y_value*globals.mouse_speed);
1549 #define store(data); if (fwrite((void *) &data, sizeof(data), 1, output)!=1) res+=1;
1551 int vtt_class :: save(FILE *rc, char *indent) {
1552 list <vtt_fx *> :: iterator effect;
1556 fprintf(rc, "%s<turntable>\n", indent);
1557 strcat(indent, "\t");
1559 store_string("name", name);
1561 store_string("audiofile", filename);
1563 store_string("audiofile", "");
1565 store_bool("sync_master", is_sync_master);
1566 store_bool("autotrigger", autotrigger);
1567 store_bool_id("loop", loop, sp_loop.get_persistence_id());
1569 store_bool_id("sync_client", is_sync_client, sp_sync_client.get_persistence_id());
1570 store_int_id("sync_cycles", sync_cycles, sp_sync_cycles.get_persistence_id());
1572 store_float_id("volume", rel_volume, sp_volume.get_persistence_id());
1573 store_float_id("pitch", rel_pitch, sp_pitch.get_persistence_id());
1574 store_bool_id("mute", mute, sp_mute.get_persistence_id());
1575 store_float_id("pan", pan, sp_pan.get_persistence_id());
1577 store_bool_id("lowpass_enable", lp_enable, sp_lp_enable.get_persistence_id());
1578 store_float_id("lowpass_gain", lp_gain, sp_lp_gain.get_persistence_id());
1579 store_float_id("lowpass_reso", lp_reso, sp_lp_reso.get_persistence_id());
1580 store_float_id("lowpass_freq", lp_freq, sp_lp_freq.get_persistence_id());
1582 store_bool_id("echo_enable", ec_enable, sp_ec_enable.get_persistence_id());
1583 store_float_id("echo_length", ec_length, sp_ec_length.get_persistence_id());
1584 store_float_id("echo_feedback", ec_feedback, sp_ec_feedback.get_persistence_id());
1585 store_float_id("echo_pan", ec_pan, sp_ec_pan.get_persistence_id());
1586 store_float_id("echo_volume", ec_volume, sp_ec_volume.get_persistence_id());
1588 store_id("speed", sp_speed.get_persistence_id());
1589 store_id("trigger", sp_trigger.get_persistence_id());
1590 store_id("spin", sp_spin.get_persistence_id());
1594 store_int("x_axis_mapping", x_par->get_persistence_id());
1598 store_int("y_axis_mapping", y_par->get_persistence_id());
1601 store_bool("audio_panel_hidden", audio_hidden);
1602 store_bool("control_panel_hidden", control_hidden);
1603 store_bool("main_panel_hidden", gui.main_panel->is_hidden());
1604 store_bool("trigger_panel_hidden", gui.trigger_panel->is_hidden());
1605 store_bool("lowpass_panel_hidden", gui.lp_panel->is_hidden());
1606 store_bool("echo_panel_hidden", gui.ec_panel->is_hidden());
1608 store_float("audio_x_zoom", gui_get_audio_x_zoom(this));
1610 fprintf(rc, "%s<fx>\n", indent);
1611 strcat(indent, "\t");
1613 for (effect=fx_list.begin(); effect!=fx_list.end(); effect++) {
1614 (*effect)->save(rc, indent);
1616 indent[strlen(indent)-1]=0;
1617 fprintf(rc, "%s</fx>\n", indent);
1619 indent[strlen(indent)-1]=0;
1620 fprintf(rc, "%s</turntable>\n", indent);
1625 #define TX_XML_SETFILE_VERSION "1.0"
1627 int vtt_class :: save_all(FILE* rc) {
1629 list <vtt_class *> :: iterator vtt;
1632 tX_seqpar :: create_persistence_ids();
1634 fprintf(rc, "<?xml version=\"1.0\" encoding=\"US-ASCII\"?>\n\n");
1635 fprintf(rc, "<terminatorXset version=\"%s\">\n", TX_XML_SETFILE_VERSION);
1637 strcpy(indent, "\t");
1639 //store_int(vtt_amount); obsolete
1641 store_float_id("master_volume", master_volume, sp_master_volume.get_persistence_id());
1642 store_float_id("master_pitch", globals.pitch, sp_master_pitch.get_persistence_id());
1644 for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++) {
1645 res+=(*vtt)->save(rc, indent);
1648 sequencer.save(rc, indent);
1650 fprintf(rc, "</terminatorXset>\n");
1655 int vtt_class :: load(xmlDocPtr doc, xmlNodePtr node) {
1666 for (xmlNodePtr cur=node->xmlChildrenNode; cur != NULL; cur = cur->next) {
1667 if (cur->type == XML_ELEMENT_NODE) {
1670 restore_string_ac("name", buffer, set_name(buffer));
1671 restore_string("audiofile", filename);
1672 restore_bool("sync_master", is_sync_master);
1673 restore_bool("autotrigger", autotrigger);
1674 restore_bool_id("loop", loop, sp_loop, nop);
1675 restore_bool_id("sync_client", is_sync_client, sp_sync_client, set_sync_client(is_sync_client, sync_cycles));
1676 restore_int_id("sync_cycles", sync_cycles, sp_sync_cycles, set_sync_client(is_sync_client, sync_cycles));
1677 restore_float_id("volume", rel_volume, sp_volume, recalc_volume());
1678 restore_float_id("pitch", rel_pitch, sp_pitch, recalc_pitch());
1679 restore_bool_id("mute", mute, sp_mute, set_mute(mute));
1680 restore_float_id("pan", pan, sp_pan, set_pan(pan));
1682 restore_bool_id("lowpass_enable", lp_enable, sp_lp_enable, lp_set_enable(lp_enable));
1683 restore_float_id("lowpass_gain", lp_gain, sp_lp_gain, lp_set_gain(lp_gain));
1684 restore_float_id("lowpass_reso", lp_reso, sp_lp_reso, lp_set_reso(lp_reso));
1685 restore_float_id("lowpass_freq", lp_freq, sp_lp_freq, lp_set_freq(lp_freq));
1687 restore_bool_id("echo_enable", ec_enable, sp_ec_enable, ec_set_enable(ec_enable));
1688 restore_float_id("echo_length", ec_length, sp_ec_length, ec_set_length(ec_length));
1689 restore_float_id("echo_feedback", ec_feedback, sp_ec_feedback, ec_set_feedback(ec_feedback));
1690 restore_float_id("echo_pan", ec_pan, sp_ec_pan, ec_set_pan(ec_pan));
1691 restore_float_id("echo_volume", ec_volume, sp_ec_volume, ec_set_volume(ec_volume));
1693 restore_id("speed", sp_speed);
1694 restore_id("trigger", sp_trigger);
1695 restore_id("spin", sp_spin);
1697 restore_int("x_axis_mapping", xpar_id);
1698 restore_int("y_axis_mapping", ypar_id);
1700 restore_bool("audio_panel_hidden", audio_hidden);
1701 restore_bool("control_panel_hidden", control_hidden);
1702 restore_bool_ac("main_panel_hidden", hidden, gui.main_panel->hide(hidden));
1703 restore_bool_ac("trigger_panel_hidden", hidden, gui.trigger_panel->hide(hidden));
1704 restore_bool_ac("lowpass_panel_hidden", hidden, gui.lp_panel->hide(hidden));
1705 restore_bool_ac("echo_panel_hidden", hidden, gui.ec_panel->hide(hidden));
1706 restore_float_ac("audio_x_zoom", tmp, gui_set_audio_x_zoom(this,tmp));
1708 if (xmlStrcmp(cur->name, (xmlChar *) "fx")==0) {
1712 for (xmlNodePtr cur=fx->xmlChildrenNode; cur != NULL; cur = cur->next) {
1713 if (cur->type == XML_ELEMENT_NODE) {
1716 if (xmlStrcmp(cur->name, (xmlChar *) "cutoff")==0) {
1717 for (unsigned int t=0; t<fx_list.size(); t++) effect_down(lp_fx);
1719 } else if (xmlStrcmp(cur->name, (xmlChar *) "lowpass")==0) {
1720 for (unsigned int t=0; t<fx_list.size(); t++) effect_down(ec_fx);
1722 } else if (xmlStrcmp(cur->name, (xmlChar *) "ladspa_plugin")==0) {
1723 xmlNodePtr pluginNode=cur;
1727 for (xmlNodePtr cur=pluginNode->xmlChildrenNode; cur!=NULL; cur = cur->next) {
1729 if (cur->type == XML_ELEMENT_NODE) {
1732 restore_int("ladspa_id", ladspa_id);
1733 if (elementFound) break;
1737 if (ladspa_id!=-1) {
1738 LADSPA_Plugin *plugin=LADSPA_Plugin::getPluginByUniqueID(ladspa_id);
1740 vtt_fx_ladspa *ladspa_effect=add_effect(plugin);
1741 ladspa_effect->load(doc, pluginNode);
1743 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);
1744 tx_note(buffer, true);
1747 tX_warning("ladspa_plugin section without a ladspa_id element.");
1751 tX_warning("unhandled element %s in fx section.", cur->name);
1758 tX_warning("unhandled element %s in turntable secion.", cur->name);
1766 set_x_input_parameter(tX_seqpar :: get_sp_by_persistence_id(xpar_id));
1768 else set_x_input_parameter(NULL);
1771 set_y_input_parameter(tX_seqpar :: get_sp_by_persistence_id(ypar_id));
1773 else set_y_input_parameter(NULL);
1779 int vtt_class :: load_all(xmlDocPtr doc, char *fname) {
1780 xmlNodePtr root=xmlDocGetRootElement(doc);
1791 tX_error("no root element? What kind of XML document is this?");
1795 if (xmlStrcmp(root->name, (const xmlChar *) "terminatorXset")) {
1796 tX_error("this is not a terminatorXset file.")
1800 if (xmlGetProp(root,(xmlChar *) "version")==NULL) {
1801 tX_error("the set file lacks a version attribute.");
1805 if (xmlStrcmp(xmlGetProp(root, (xmlChar *) "version"), (xmlChar *) TX_XML_SETFILE_VERSION)) {
1806 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);
1809 /* delete current tables... */
1810 while (main_list.size()) {
1811 delete((*main_list.begin()));
1816 /* counting turntables.. */
1817 for (xmlNodePtr cur=root->xmlChildrenNode; cur != NULL; cur = cur->next) {
1818 if (cur->type == XML_ELEMENT_NODE) {
1819 if (xmlStrcmp(cur->name, (xmlChar *) "turntable")==0) {
1825 tX_debug("Found %i turntables in set.", table_ctr);
1827 ld_create_loaddlg(TX_LOADDLG_MODE_MULTI, table_ctr);
1828 ld_set_setname(fname);
1831 for (xmlNodePtr cur=root->xmlChildrenNode; cur != NULL; cur = cur->next) {
1832 if (cur->type == XML_ELEMENT_NODE) {
1835 restore_float_id("master_volume", master_volume, sp_master_volume, set_master_volume(master_volume));
1836 restore_float_id("master_pitch", globals.pitch, sp_master_pitch, set_master_pitch(globals.pitch));
1838 if ((!elementFound) && (xmlStrcmp(cur->name, (xmlChar *) "turntable")==0)) {
1840 vtt_class *vtt=new vtt_class(1);
1841 vtt->load(doc, cur);
1843 tX_debug("loading a turntable..");
1845 if (strlen(vtt->filename)) {
1846 strcpy(fn_buff, vtt->filename);
1847 ld_set_filename(fn_buff);
1849 restmp=(int) vtt->load_file(fn_buff);
1853 gtk_box_pack_start(GTK_BOX(control_parent), vtt->gui.control_box, TRUE, TRUE, 0);
1854 gtk_box_pack_start(GTK_BOX(audio_parent), vtt->gui.audio_box, TRUE, TRUE, 0);
1855 if (vtt->audio_hidden) vtt->hide_audio(vtt->audio_hidden);
1856 if (vtt->control_hidden) vtt->hide_control(vtt->control_hidden);
\r
1858 if ((!elementFound) && (xmlStrcmp(cur->name, (xmlChar *) "sequencer")==0)) {
1860 sequencer.load(doc, cur);
1862 if (!elementFound) {
1863 tX_warning("unhandled element %s in setfile %s", cur->name, fname);
1873 void add_vtt(GtkWidget *ctrl, GtkWidget *audio, char *fn)
1876 hmmpg = new vtt_class(1);
1877 gtk_box_pack_start(GTK_BOX(ctrl), hmmpg->gui.control_box, TRUE, TRUE, 0);
1878 gtk_box_pack_start(GTK_BOX(audio), hmmpg->gui.audio_box, TRUE, TRUE, 0);
1879 if (fn) hmmpg->load_file(fn);
1882 extern void vg_move_fx_panel_up(GtkWidget *wid, vtt_class *vtt);
1883 extern void vg_move_fx_panel_down(GtkWidget *wid, vtt_class *vtt);
1885 //#define debug_fx_stack(); for (i=fx_list.begin(); i != fx_list.end(); i++) puts((*i)->get_info_string());
1886 #define debug_fx_stack();
1888 void vtt_class :: effect_up(vtt_fx *effect)
1890 list <vtt_fx *> :: iterator i;
1891 list <vtt_fx *> :: iterator previous;
1896 if ((*fx_list.begin())==effect) return;
1898 for (previous=i=fx_list.begin(); i != fx_list.end(); i++)
1910 pthread_mutex_lock(&render_lock);
1911 fx_list.remove(effect);
1912 fx_list.insert(previous, effect);
1913 pthread_mutex_unlock(&render_lock);
1915 vg_move_fx_panel_up(effect->get_panel_widget(), this);
1921 void vtt_class :: effect_down(vtt_fx *effect)
1923 list <vtt_fx *> :: iterator i;
1928 for (i=fx_list.begin(); i != fx_list.end(); i++)
1937 if ((ok) && (i!=fx_list.end()))
1940 if (i==fx_list.end()) return;
1943 pthread_mutex_lock(&render_lock);
1944 fx_list.remove(effect);
1946 fx_list.insert(i, effect);
1947 vg_move_fx_panel_down(effect->get_panel_widget(), this);
1948 pthread_mutex_unlock(&render_lock);
1954 void vtt_class :: effect_remove(vtt_fx_ladspa *effect)
1956 pthread_mutex_lock(&render_lock);
1957 fx_list.remove(effect);
1958 pthread_mutex_unlock(&render_lock);
1963 extern void gui_hide_control_panel(vtt_class *vtt, bool hide);
1964 extern void gui_hide_audio_panel(vtt_class *vtt, bool hide);
1966 void vtt_class :: hide_audio(bool hide) {
1968 gui_hide_audio_panel(this, hide);
1971 void vtt_class :: hide_control(bool hide) {
1972 control_hidden=hide;
1973 gui_hide_control_panel(this, hide);