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
cleanup_required=false;
103
sprintf (name, "Turntable %i", vtt_amount);
104
strcpy(filename, "NONE");
113
audiofile_pitch_correction=1.0;
115
ec_output_buffer=NULL;
134
lp_setup(lp_gain, lp_reso, lp_freq);
145
main_list.push_back(this);
147
/* "connecting" the seq-parameters */
149
sp_speed.set_vtt((void *) this);
150
sp_volume.set_vtt((void *) this);
151
sp_pitch.set_vtt((void *) this);
152
sp_pan.set_vtt((void *) this);
153
sp_trigger.set_vtt((void *) this);
154
sp_loop.set_vtt((void *) this);
155
sp_sync_client.set_vtt((void *) this);
156
sp_sync_cycles.set_vtt((void *) this);
157
sp_lp_enable.set_vtt((void *) this);
158
sp_lp_gain.set_vtt((void *) this);
159
sp_lp_reso.set_vtt((void *) this);
160
sp_lp_freq.set_vtt((void *) this);
161
sp_ec_enable.set_vtt((void *) this);
162
sp_ec_length.set_vtt((void *) this);
163
sp_ec_pan.set_vtt((void *) this);
164
sp_ec_volume.set_vtt((void *) this);
165
sp_ec_feedback.set_vtt((void *) this);
166
sp_mute.set_vtt((void *) this);
167
sp_spin.set_vtt((void *) this);
172
lp_fx=new vtt_fx_lp();
173
lp_fx->set_vtt((void *) this);
174
fx_list.push_back(lp_fx);
176
ec_fx=new vtt_fx_ec();
177
ec_fx->set_vtt((void *) this);
178
fx_list.push_back(ec_fx);
183
lp_fx->set_panel_widget(gui.lp_panel->get_widget());
184
ec_fx->set_panel_widget(gui.ec_panel->get_widget());
189
set_master_volume(globals.volume);
190
set_output_buffer_size(samples_in_mix_buffer/2);
193
audiofile_pitch_correction=1.0;
201
control_hidden=false;
208
vtt_class :: ~vtt_class()
213
main_list.remove(this);
214
if (audiofile) delete audiofile;
215
//if (buffer) free(buffer);
216
if (output_buffer) tX_freemem(output_buffer, "output_buffer", "vtt Destructor");
219
if (mix_solo) solo_ctr--;
221
while (fx_list.size())
223
effect=(*fx_list.begin());
224
fx_list.remove(effect);
228
if (sync_master==this) {
235
void vtt_class :: set_name(char *newname)
237
strcpy(name, newname);
238
gui_set_name(this, name);
241
tX_audio_error vtt_class :: load_file(char *fname)
244
int was_playing=is_playing;
246
if (is_playing) stop();
248
if (audiofile) delete(audiofile);
256
audiofile=new tx_audiofile();
257
res=audiofile->load(fname);
259
if (res==TX_AUDIO_SUCCESS) {
260
buffer=audiofile->get_buffer();
261
double file_rate=audiofile->get_sample_rate();
262
audiofile_pitch_correction=file_rate/((double) last_sample_rate);
264
samples_in_buffer=audiofile->get_no_samples();
265
pos_i_max=samples_in_buffer-1;
266
maxpos=audiofile->get_no_samples();
267
strcpy(filename, fname);
268
if (was_playing) trigger();
269
// printf("Successfully loaded %s, %08x, %i\n", fname, buffer, samples_in_buffer);
274
gui_update_display(this);
276
ec_set_length(ec_length);
281
int vtt_class :: set_output_buffer_size(int newsize)
283
list <vtt_fx *> :: iterator effect;
285
if (ec_output_buffer) tX_freemem(ec_output_buffer, "ec_output_buffer", "vtt set_output_buffer_size()");
286
tX_malloc(ec_output_buffer, "ec_output_buffer", "vtt set_output_buffer_size()", sizeof(float)*newsize, (float *));
288
if (output_buffer) tX_freemem(output_buffer, "output_buffer", "vtt set_output_buffer_size()");
289
tX_malloc(output_buffer, "output_buffer", "vtt set_output_buffer_size()", sizeof(float)*newsize, (float *));
291
end_of_outputbuffer = output_buffer + newsize; //size_t(sizeof(float)*(newsize));
293
samples_in_outputbuffer=newsize;
294
inv_samples_in_outputbuffer=1.0/samples_in_outputbuffer;
296
for (effect=fx_list.begin(); effect != fx_list.end(); effect++)
298
(*effect)->reconnect_buffer();
301
if (output_buffer) return(0);
305
void vtt_class :: set_volume(f_prec newvol)
311
void vtt_class :: recalc_volume()
313
res_volume=rel_volume*res_master_volume;
314
f_prec ec_res_volume=res_volume*ec_volume;
318
res_volume_left=(1.0-pan)*res_volume;
319
res_volume_right=res_volume;
323
res_volume_left=res_volume;
324
res_volume_right=(1.0+pan)*res_volume;
328
res_volume_left=res_volume_right=res_volume;
333
ec_volume_left=(1.0-ec_pan)*ec_res_volume;
334
ec_volume_right=ec_res_volume;
338
ec_volume_left=ec_res_volume;
339
ec_volume_right=(1.0+ec_pan)*ec_res_volume;
343
ec_volume_left=ec_volume_right=ec_res_volume;
345
// printf("vtt_volume: %f, %f, l: %f, r: %f\n", rel_volume, res_volume, res_volume_left, res_volume_right);
348
void vtt_class :: set_pan(f_prec newpan)
354
void vtt_class :: set_pitch(f_prec newpitch)
360
void vtt_class :: recalc_pitch()
362
res_pitch=globals.pitch*rel_pitch;
363
res_pitch*=audiofile_pitch_correction;
365
ec_set_length(ec_length);
368
void vtt_class :: set_autotrigger(int newstate)
370
autotrigger=newstate;
373
void vtt_class :: set_loop(int newstate)
378
void vtt_class :: set_mute(int newstate)
384
void vtt_class :: set_mix_mute(int newstate)
390
void vtt_class :: set_mix_solo(int newstate)
392
if (mix_solo && !newstate)
398
else if (!mix_solo && newstate)
407
list <vtt_class *> :: iterator vtt;
409
for (vtt=main_list.begin(); vtt!=main_list.end() ; vtt++)
415
void vtt_class :: lp_set_enable (int newstate)
421
void vtt_class :: lp_reset()
426
void vtt_class :: lp_set_gain (f_prec gain)
429
lp_resgain=lp_gain*lp_autogain;
432
void vtt_class :: lp_set_reso(f_prec reso)
436
lp_b=reso*(1.0+(1.0/lp_a));
437
lp_autogain=1.0-reso*GAIN_AUTO_ADJUST;
438
lp_resgain=lp_gain*lp_autogain;
441
void vtt_class :: lp_set_freq(f_prec freq)
446
lp_b=lp_reso*(1.0+(1.0/lp_a));
449
void vtt_class :: lp_setup(f_prec gain, f_prec reso, f_prec freq)
455
lp_b=reso*(1.0+(1.0/lp_a));
457
lp_autogain=1.0-reso*GAIN_AUTO_ADJUST;
458
lp_resgain=lp_gain*lp_autogain;
461
void vtt_class :: ec_set_enable(int newstate)
468
void vtt_class :: ec_set_pan(f_prec pan)
475
/* Max length is 1.0 */
477
void vtt_class :: ec_set_length(f_prec length)
484
ec_res_length=length*samples_in_buffer;
488
ec_res_length=length*samples_in_buffer/res_pitch;
491
if (ec_res_length<0) ec_res_length*=-1;
493
if (ec_res_length>=EC_MAX_BUFFER)
495
ec_res_length=EC_MAX_BUFFER*length;
498
delay=(int )floor(ec_res_length);
500
ec_delay=&ec_buffer[delay];
503
void vtt_class :: ec_set_feedback(f_prec feedback)
505
ec_feedback=feedback;
509
void vtt_class :: ec_set_volume(f_prec volume)
515
void vtt_class :: ec_clear_buffer()
519
for (ptr=ec_buffer; ptr<=ec_delay; ptr++) {
525
void vtt_class :: render()
527
list <vtt_fx *> :: iterator effect;
530
if (sense_cycles>0) {
532
if (sense_cycles==0) sp_speed.receive_input_value(0);
537
for (effect=fx_list.begin(); effect != fx_list.end(); effect++) {
538
if ((*effect)->isEnabled()) (*effect)->run();
542
extern void vg_create_fx_gui(vtt_class *vtt, vtt_fx_ladspa *effect, LADSPA_Plugin *plugin);
544
vtt_fx_ladspa * vtt_class :: add_effect (LADSPA_Plugin *plugin)
546
vtt_fx_ladspa *new_effect;
548
new_effect = new vtt_fx_ladspa (plugin, this);
549
pthread_mutex_lock(&render_lock);
550
fx_list.push_back(new_effect);
551
if (is_playing) new_effect->activate();
552
pthread_mutex_unlock(&render_lock);
553
vg_create_fx_gui(this, new_effect, plugin);
558
void vtt_class :: calc_speed()
564
if (speed != speed_target) {
566
speed_step=speed_target-speed_real;
567
speed_step/=globals.vtt_inertia;
570
if (speed_target != speed_real) {
571
speed_real+=speed_step;
572
if ((speed_step<0) && (speed_real<speed_target)) speed_real=speed_target;
573
else if ((speed_step>0) && (speed_real>speed_target)) speed_real=speed_target;
577
if ((speed_last==0) && (speed_real !=0)) {
582
if ((speed_last!=0) && (speed_real==0)) {
588
speed_last = speed_real;
590
if (res_mute != res_mute_old) {
592
fade_out=1; fade_in=0;
595
fade_in=1; fade_out=0;
598
res_mute_old=res_mute;
600
if (res_mute) do_mute=1;
604
void vtt_class :: render_scratch()
625
for (sample =0,out=output_buffer, fade_vol=0.0; sample < samples_in_outputbuffer;sample++, out++, fade_vol+=inv_samples_in_outputbuffer) {
626
if ((speed_real!=0) || (fade_out)) {
637
master_triggered_at=sample;
643
} else if (pos_f<0) {
650
master_triggered_at=sample;
658
pos_a_f=floor(pos_f);
659
pos_i=(unsigned int) pos_a_f;
661
amount_b=pos_f-pos_a_f;
662
amount_a=1.0-amount_b;
668
sample_a=(f_prec) *ptr;
670
if (pos_i == pos_i_max) {
674
sample_b=(f_prec) *ptr;
677
sample_res=(sample_a*amount_a)+(sample_b*amount_b);
680
sample_res*=fade_vol;
681
} else if (fade_out) {
682
sample_res*=1.0-fade_vol;
693
void vtt_class :: forward_turntable()
704
if ((speed_real==0) && (!fade_out)) return;
707
/* following code is problematic as adding speed_real*n is
708
different from adding speed_real n times to pos_f.
710
well it speeds things up quite a bit and double precision
711
seems to do a satisfying job.
713
#define pos_f_test to prove that.
716
pos_f_tmp=pos_f+speed_real*samples_in_outputbuffer;
718
if ((pos_f_tmp > 0) && (pos_f_tmp < maxpos)) {
727
/* now the slow way ;) */
729
for (sample =0; sample < samples_in_outputbuffer; sample++) {
736
if (is_sync_master) {
738
master_triggered_at=sample;
744
} else if (pos_f<0) {
748
if (is_sync_master) {
750
master_triggered_at=sample;
760
diff=pos_f_tmp-pos_f;
761
if (diff!=0) printf("fast: %f, slow: %f, diff: %f, tt: %s\n", pos_f_tmp, pos_f, diff, name);
767
The following lowpass filter is based on some sample code by
768
Paul Kellett <paul.kellett@maxim.abel.co.uk>
771
void vtt_class :: render_lp()
775
for (sample = output_buffer; sample<end_of_outputbuffer; sample++) {
776
lp_buf0 = lp_a * lp_buf0 + lp_freq * ((*sample)*lp_resgain + lp_b * (lp_buf0 - lp_buf1));
777
lp_buf1 = lp_a * lp_buf1 + lp_freq * lp_buf0;
783
void vtt_class :: render_ec()
789
for (i=0, sample = output_buffer, ec_sample=ec_output_buffer; i<samples_in_outputbuffer; i++, ec_sample++,sample++, ec_ptr++) {
790
if (ec_ptr>ec_delay) ec_ptr=ec_buffer;
791
*ec_sample=(*ec_ptr) *ec_feedback;
792
*ec_ptr=*sample+*ec_sample;
796
int vtt_class :: set_mix_buffer_size(int no_samples)
798
list <vtt_class *> :: iterator vtt;
801
// printf("vtt_class::set_mix_buffer_size(), mix_buffer: %12x, mix_out: %12x, samples: %i\n", mix_buffer, mix_out_buffer, no_samples);
803
if (mix_buffer) tX_freemem(mix_buffer, "mix_buffer", "vtt set_mix_buffer_size()");
804
samples_in_mix_buffer=no_samples*2;
806
tX_malloc(mix_buffer, "mix_buffer", "vtt set_mix_buffer_size()", sizeof(float)*samples_in_mix_buffer, (float *));
807
mix_buffer_end=mix_buffer+samples_in_mix_buffer;
809
// printf("mix_buffer: %12x\n", mix_buffer);
810
// printf("mix_samples: %i, out_samples: %i", samples_in_mix_buffer, no_samples);
812
if (mix_out_buffer) tX_freemem(mix_out_buffer, "mix_out_buffer", "vtt set_mix_buffer_size()");
813
tX_malloc(mix_out_buffer, "mix_out_buffer", "vtt set_mix_buffer_size()", sizeof(int16_t)*samples_in_mix_buffer + 4, (int16_t *));
815
// printf("mix_out_buffer: %12x\n", mix_out_buffer);
817
for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++) {
818
res|=(*vtt)->set_output_buffer_size(no_samples);
821
if ((!mix_buffer) || (!mix_out_buffer) || res) return(1);
823
mix_buffer_size=no_samples;
828
int16_t * vtt_class :: render_all_turntables()
830
list <vtt_class *> :: iterator vtt, next;
837
pthread_mutex_lock(&render_lock);
839
if (render_list.size()==0) {
840
memset((void *) mix_out_buffer, 0, sizeof(int16_t)*samples_in_mix_buffer);
841
/* We need to memset mix_buffer, too, as the JACK backend
842
acesses this directly.
844
memset((void *) mix_buffer, 0, sizeof(float)*samples_in_mix_buffer);
846
vtt=render_list.begin();
848
max=(*vtt)->max_value;
851
for (sample=0, mix_sample=0; sample<(*vtt)->samples_in_outputbuffer; sample++) {
852
temp=(*vtt)->output_buffer[sample];
853
mix_buffer[mix_sample]=temp*(*vtt)->res_volume_left;
855
mix_buffer[mix_sample]=temp*(*vtt)->res_volume_right;
858
if (temp>max) max=temp;
859
else if (temp<min) min=temp;
863
if (min>max) (*vtt)->max_value=min; else (*vtt)->max_value=max;
865
if ((*vtt)->ec_enable) {
866
for (sample=0, mix_sample=0; sample<(*vtt)->samples_in_outputbuffer; sample++) {
867
temp=(*vtt)->ec_output_buffer[sample];
869
mix_buffer[mix_sample]+=temp*(*vtt)->ec_volume_left;
871
mix_buffer[mix_sample]+=temp*(*vtt)->ec_volume_right;
876
if (master_triggered) {
877
for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++) {
878
if ((*vtt)->is_sync_client) {
879
if ((*vtt)->sync_countdown) {
880
(*vtt)->sync_countdown--;
882
(*vtt)->sync_countdown=(*vtt)->sync_cycles;
883
(*vtt)->trigger(false);
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();
1030
void vtt_class :: retrigger()
1032
if (res_pitch>=0) pos_f=0;
1037
speed_real=res_pitch;
1038
speed_target=res_pitch;
1043
if (is_sync_master) {
1045
master_triggered_at=0;
1049
int vtt_class :: trigger(bool need_lock)
1051
list <vtt_fx *> :: iterator effect;
1053
if (!buffer) return 1;
1058
if (need_lock) pthread_mutex_lock(&render_lock);
1060
cleanup_required=false;
1062
/* activating plugins */
1063
for (effect=fx_list.begin(); effect != fx_list.end(); effect++) {
1064
(*effect)->activate();
1067
if (is_sync_master) {
1068
render_list.push_front(this);
1070
render_list.push_back(this);
1073
if (need_lock) pthread_mutex_unlock(&render_lock);
1079
/* call this only when owning render_lock. */
1080
int vtt_class :: stop_nolock()
1082
list <vtt_fx *> :: iterator effect;
1088
render_list.remove(this);
1093
cleanup_required=true;
1095
/* deactivating plugins */
1096
for (effect=fx_list.begin(); effect != fx_list.end(); effect++) {
1097
(*effect)->deactivate();
1103
int vtt_class :: stop()
1107
pthread_mutex_lock(&render_lock);
1109
pthread_mutex_unlock(&render_lock);
1114
void vtt_class :: set_sync_master(int master)
1117
if (sync_master) sync_master->set_sync_master(0);
1121
if (sync_master==this) sync_master=0;
1123
gui_clear_master_button(this);
1127
void vtt_class :: set_sync_client(int slave, int cycles)
1129
tX_debug("vtt_class::set_sync_client() setting %i, %i.", slave, cycles);
1130
is_sync_client=slave;
1132
// sync_countdown=cycles;
1136
void vtt_class :: set_sync_client_ug(int slave, int cycles)
1138
set_sync_client(slave, cycles);
1141
void vtt_class :: set_master_volume(f_prec new_volume)
1143
list <vtt_class *> :: iterator vtt;
1145
master_volume=new_volume;
1146
globals.volume=new_volume;
1148
if (main_list.size()>0) {
1149
vol_channel_adjust=sqrt((f_prec) main_list.size());
1150
res_master_volume=master_volume/vol_channel_adjust;
1153
for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++) {
1154
(*vtt)->recalc_volume();
1158
void vtt_class :: set_master_pitch(f_prec new_pitch)
1160
list <vtt_class *> :: iterator vtt;
1162
globals.pitch=new_pitch;
1163
for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++) {
1164
(*vtt)->recalc_pitch();
1168
void vtt_class :: focus_no(int no)
1170
list <vtt_class *> :: iterator vtt;
1175
for (i=0, vtt=main_list.begin(); vtt!=main_list.end(); vtt++, i++) {
1182
void vtt_class :: focus_next()
1184
list <vtt_class *> :: iterator vtt;
1187
if (main_list.size()) {
1188
focused_vtt=(*main_list.begin());
1193
for (vtt=main_list.begin(); vtt!=main_list.end() ; vtt++) {
1194
if ((*vtt)==focused_vtt) {
1195
/* Ok, we found ourselves.. */
1198
while ((vtt!=main_list.end()) && ((*vtt)->audio_hidden) ) {
1202
if (vtt==main_list.end()) {
1203
/* No other "focusable" after this vtt so we're looking for the next */
1205
for (vtt=main_list.begin(); vtt!=main_list.end() ; vtt++) {
1206
if (! (*vtt)->audio_hidden) {
1211
/* When we get here there's no "focusable" vtt at all... damn */
1221
focused_vtt=(*main_list.begin());
1224
void vtt_class :: set_scratch(int newstate)
1227
sp_spin.receive_input_value(0);
1229
sense_cycles=globals.sense_cycles;
1231
sp_spin.receive_input_value(1);
1237
void vtt_class :: unfocus()
1242
void vtt_class :: set_x_input_parameter(tX_seqpar *sp)
1247
void vtt_class :: set_y_input_parameter(tX_seqpar *sp)
1252
void vtt_class :: xy_input(f_prec x_value, f_prec y_value)
1254
if (x_par) x_par->handle_mouse_input(x_value*globals.mouse_speed);
1255
if (y_par) y_par->handle_mouse_input(y_value*globals.mouse_speed);
1258
#define store(data); if (fwrite((void *) &data, sizeof(data), 1, output)!=1) res+=1;
1260
int vtt_class :: save(FILE *rc, gzFile rz, char *indent) {
1261
list <vtt_fx *> :: iterator effect;
1262
char tmp_xml_buffer[4096];
1266
tX_store("%s<turntable>\n", indent);
1267
strcat(indent, "\t");
1269
store_string("name", name);
1271
store_string("audiofile", filename);
1273
store_string("audiofile", "");
1275
store_bool("sync_master", is_sync_master);
1276
store_bool("autotrigger", autotrigger);
1277
store_bool_sp("loop", loop, sp_loop);
1279
store_bool_sp("sync_client", is_sync_client, sp_sync_client);
1280
store_int_sp("sync_cycles", sync_cycles, sp_sync_cycles);
1282
store_float_sp("volume", rel_volume, sp_volume);
1283
store_float_sp("pitch", rel_pitch, sp_pitch);
1284
store_bool_sp("mute", mute, sp_mute);
1285
store_float_sp("pan", pan, sp_pan);
1287
store_bool_sp("lowpass_enable", lp_enable, sp_lp_enable);
1288
store_float_sp("lowpass_gain", lp_gain, sp_lp_gain);
1289
store_float_sp("lowpass_reso", lp_reso, sp_lp_reso);
1290
store_float_sp("lowpass_freq", lp_freq, sp_lp_freq);
1292
store_bool_sp("echo_enable", ec_enable, sp_ec_enable);
1293
store_float_sp("echo_length", ec_length, sp_ec_length);
1294
store_float_sp("echo_feedback", ec_feedback, sp_ec_feedback);
1295
store_float_sp("echo_pan", ec_pan, sp_ec_pan);
1296
store_float_sp("echo_volume", ec_volume, sp_ec_volume);
1298
store_id("speed", sp_speed.get_persistence_id());
1299
store_id("trigger", sp_trigger.get_persistence_id());
1300
store_id("spin", sp_spin.get_persistence_id());
1304
store_int("x_axis_mapping", x_par->get_persistence_id());
1308
store_int("y_axis_mapping", y_par->get_persistence_id());
1311
store_bool("audio_panel_hidden", audio_hidden);
1312
store_bool("control_panel_hidden", control_hidden);
1313
store_bool("main_panel_hidden", gui.main_panel->is_hidden());
1314
store_bool("trigger_panel_hidden", gui.trigger_panel->is_hidden());
1315
store_bool("lowpass_panel_hidden", gui.lp_panel->is_hidden());
1316
store_bool("echo_panel_hidden", gui.ec_panel->is_hidden());
1318
store_bool("mix_mute", mix_mute);
1319
store_bool("mix_solo", mix_solo);
1321
store_float("audio_x_zoom", gui_get_audio_x_zoom(this));
1323
tX_store("%s<fx>\n", indent);
1324
strcat(indent, "\t");
1326
for (effect=fx_list.begin(); effect!=fx_list.end(); effect++) {
1327
(*effect)->save(rc, rz, indent);
1329
indent[strlen(indent)-1]=0;
1330
tX_store("%s</fx>\n", indent);
1332
indent[strlen(indent)-1]=0;
1333
tX_store("%s</turntable>\n", indent);
1338
#define TX_XML_SETFILE_VERSION "1.0"
1340
int vtt_class :: save_all(FILE* rc, gzFile rz) {
1342
list <vtt_class *> :: iterator vtt;
1345
tX_seqpar :: create_persistence_ids();
1347
tX_store("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n");
1348
tX_store("<terminatorXset version=\"%s\">\n", TX_XML_SETFILE_VERSION);
1350
strcpy(indent, "\t");
1352
//store_int(vtt_amount); obsolete
1354
store_float_sp("master_volume", master_volume, sp_master_volume);
1355
store_float_sp("master_pitch", globals.pitch, sp_master_pitch);
1357
for (vtt=main_list.begin(); vtt!=main_list.end(); vtt++) {
1358
res+=(*vtt)->save(rc, rz, indent);
1361
sequencer.save(rc, rz, indent);
1363
tX_store("</terminatorXset>\n");
1368
int vtt_class :: load(xmlDocPtr doc, xmlNodePtr node) {
1378
char tmp_xml_buffer[4096];
1380
for (xmlNodePtr cur=node->xmlChildrenNode; cur != NULL; cur = cur->next) {
1381
if (cur->type == XML_ELEMENT_NODE) {
1384
restore_string_ac("name", buffer, set_name(buffer));
1385
restore_string("audiofile", filename);
1386
restore_bool("sync_master", is_sync_master);
1387
restore_bool("autotrigger", autotrigger);
1388
restore_bool_id("loop", loop, sp_loop, nop);
1389
restore_bool_id("sync_client", is_sync_client, sp_sync_client, set_sync_client(is_sync_client, sync_cycles));
1390
restore_int_id("sync_cycles", sync_cycles, sp_sync_cycles, set_sync_client(is_sync_client, sync_cycles));
1391
restore_float_id("volume", rel_volume, sp_volume, recalc_volume());
1392
restore_float_id("pitch", rel_pitch, sp_pitch, recalc_pitch());
1393
restore_bool_id("mute", mute, sp_mute, set_mute(mute));
1394
restore_float_id("pan", pan, sp_pan, set_pan(pan));
1396
restore_bool_id("lowpass_enable", lp_enable, sp_lp_enable, lp_set_enable(lp_enable));
1397
restore_float_id("lowpass_gain", lp_gain, sp_lp_gain, lp_set_gain(lp_gain));
1398
restore_float_id("lowpass_reso", lp_reso, sp_lp_reso, lp_set_reso(lp_reso));
1399
restore_float_id("lowpass_freq", lp_freq, sp_lp_freq, lp_set_freq(lp_freq));
1401
restore_bool_id("echo_enable", ec_enable, sp_ec_enable, ec_set_enable(ec_enable));
1402
restore_float_id("echo_length", ec_length, sp_ec_length, ec_set_length(ec_length));
1403
restore_float_id("echo_feedback", ec_feedback, sp_ec_feedback, ec_set_feedback(ec_feedback));
1404
restore_float_id("echo_pan", ec_pan, sp_ec_pan, ec_set_pan(ec_pan));
1405
restore_float_id("echo_volume", ec_volume, sp_ec_volume, ec_set_volume(ec_volume));
1407
restore_id("speed", sp_speed);
1408
restore_id("trigger", sp_trigger);
1409
restore_id("spin", sp_spin);
1411
restore_int("x_axis_mapping", xpar_id);
1412
restore_int("y_axis_mapping", ypar_id);
1414
restore_bool("mix_mute", mix_mute);
1415
restore_bool("mix_solo", mix_solo);
1417
restore_bool("audio_panel_hidden", audio_hidden);
1418
restore_bool("control_panel_hidden", control_hidden);
1419
restore_bool_ac("main_panel_hidden", hidden, gui.main_panel->hide(hidden));
1420
restore_bool_ac("trigger_panel_hidden", hidden, gui.trigger_panel->hide(hidden));
1421
restore_bool_ac("lowpass_panel_hidden", hidden, gui.lp_panel->hide(hidden));
1422
restore_bool_ac("echo_panel_hidden", hidden, gui.ec_panel->hide(hidden));
1423
restore_float_ac("audio_x_zoom", tmp, gui_set_audio_x_zoom(this,tmp));
1424
vg_adjust_zoom(gui.zoom, this);
1426
if (xmlStrcmp(cur->name, (xmlChar *) "fx")==0) {
1430
for (xmlNodePtr cur=fx->xmlChildrenNode; cur != NULL; cur = cur->next) {
1431
if (cur->type == XML_ELEMENT_NODE) {
1434
if (xmlStrcmp(cur->name, (xmlChar *) "cutoff")==0) {
1435
for (unsigned int t=0; t<fx_list.size(); t++) effect_down(lp_fx);
1437
} else if (xmlStrcmp(cur->name, (xmlChar *) "lowpass")==0) {
1438
for (unsigned int t=0; t<fx_list.size(); t++) effect_down(ec_fx);
1440
} else if (xmlStrcmp(cur->name, (xmlChar *) "ladspa_plugin")==0) {
1441
xmlNodePtr pluginNode=cur;
1445
for (xmlNodePtr cur=pluginNode->xmlChildrenNode; cur!=NULL; cur = cur->next) {
1447
if (cur->type == XML_ELEMENT_NODE) {
1450
restore_int("ladspa_id", ladspa_id);
1451
if (elementFound) break;
1455
if (ladspa_id!=-1) {
1456
LADSPA_Plugin *plugin=LADSPA_Plugin::getPluginByUniqueID(ladspa_id);
1458
vtt_fx_ladspa *ladspa_effect=add_effect(plugin);
1459
ladspa_effect->load(doc, pluginNode);
1461
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);
1462
tx_note(buffer, true);
1465
tX_warning("ladspa_plugin section without a ladspa_id element.");
1469
tX_warning("unhandled element %s in fx section.", cur->name);
1476
tX_warning("unhandled element %s in turntable secion.", cur->name);
1488
set_x_input_parameter(tX_seqpar :: get_sp_by_persistence_id(xpar_id));
1490
else set_x_input_parameter(NULL);
1493
set_y_input_parameter(tX_seqpar :: get_sp_by_persistence_id(ypar_id));
1495
else set_y_input_parameter(NULL);
1497
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gui.mute), mix_mute);
1498
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gui.solo), mix_solo);
1503
void vtt_class :: delete_all()
1505
while (main_list.size()) {
1506
delete((*main_list.begin()));
1509
/* Take care of the master events.. */
1510
sequencer.delete_all_events(tX_sequencer::DELETE_ALL);
1512
/* Now reset master settings ot the default: */
1513
set_master_pitch(1.0);
1514
set_master_volume(1.0);
1516
sp_master_pitch.do_exec(1.0);
1517
sp_master_pitch.do_update_graphics();
1519
sp_master_volume.do_exec(1.0);
1520
sp_master_volume.do_update_graphics();
1522
/* Remove master MIDI mappings... */
1523
sp_master_pitch.bound_midi_event.type=tX_midievent::NONE;
1524
sp_master_volume.bound_midi_event.type=tX_midievent::NONE;
1529
int vtt_class :: load_all(xmlDocPtr doc, char *fname) {
1530
xmlNodePtr root=xmlDocGetRootElement(doc);
1538
tX_error("no root element? What kind of XML document is this?");
1542
if (xmlStrcmp(root->name, (const xmlChar *) "terminatorXset")) {
1543
tX_error("this is not a terminatorXset file.")
1547
if (xmlGetProp(root,(xmlChar *) "version")==NULL) {
1548
tX_error("the set file lacks a version attribute.");
1552
if (xmlStrcmp(xmlGetProp(root, (xmlChar *) "version"), (xmlChar *) TX_XML_SETFILE_VERSION)) {
1553
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);
1556
/* delete current tables... */
1561
/* counting turntables.. */
1562
for (xmlNodePtr cur=root->xmlChildrenNode; cur != NULL; cur = cur->next) {
1563
if (cur->type == XML_ELEMENT_NODE) {
1564
if (xmlStrcmp(cur->name, (xmlChar *) "turntable")==0) {
1570
tX_debug("Found %i turntables in set.", table_ctr);
1572
ld_create_loaddlg(TX_LOADDLG_MODE_MULTI, table_ctr);
1573
ld_set_setname(fname);
1576
for (xmlNodePtr cur=root->xmlChildrenNode; cur != NULL; cur = cur->next) {
1577
if (cur->type == XML_ELEMENT_NODE) {
1580
restore_float_id("master_volume", master_volume, sp_master_volume, set_master_volume(master_volume));
1581
restore_float_id("master_pitch", globals.pitch, sp_master_pitch, set_master_pitch(globals.pitch));
1583
if ((!elementFound) && (xmlStrcmp(cur->name, (xmlChar *) "turntable")==0)) {
1585
vtt_class *vtt=new vtt_class(1);
1586
vtt->load(doc, cur);
1588
tX_debug("loading a turntable..");
1590
if (strlen(vtt->filename)) {
1591
strcpy(fn_buff, vtt->filename);
1592
ld_set_filename(fn_buff);
1594
restmp=(int) vtt->load_file(fn_buff);
1598
gtk_box_pack_start(GTK_BOX(control_parent), vtt->gui.control_box, TRUE, TRUE, 0);
1599
gtk_box_pack_start(GTK_BOX(audio_parent), vtt->gui.audio_box, TRUE, TRUE, 0);
1600
if (vtt->audio_hidden) vtt->hide_audio(vtt->audio_hidden);
1601
if (vtt->control_hidden) vtt->hide_control(vtt->control_hidden);
1603
if ((!elementFound) && (xmlStrcmp(cur->name, (xmlChar *) "sequencer")==0)) {
1605
sequencer.load(doc, cur);
1607
if (!elementFound) {
1608
tX_warning("unhandled element %s in setfile %s", cur->name, fname);
1613
sp_master_volume.do_update_graphics();
1614
sp_master_pitch.do_update_graphics();
1621
void add_vtt(GtkWidget *ctrl, GtkWidget *audio, char *fn)
1624
new_tt = new vtt_class(1);
1625
gtk_box_pack_start(GTK_BOX(ctrl), new_tt->gui.control_box, TRUE, TRUE, 0);
1626
gtk_box_pack_start(GTK_BOX(audio), new_tt->gui.audio_box, TRUE, TRUE, 0);
1627
if (fn) new_tt->load_file(fn);
1630
extern void vg_move_fx_panel_up(GtkWidget *wid, vtt_class *vtt);
1631
extern void vg_move_fx_panel_down(GtkWidget *wid, vtt_class *vtt);
1633
//#define debug_fx_stack(); for (i=fx_list.begin(); i != fx_list.end(); i++) puts((*i)->get_info_string());
1634
#define debug_fx_stack();
1636
void vtt_class :: effect_up(vtt_fx *effect)
1638
list <vtt_fx *> :: iterator i;
1639
list <vtt_fx *> :: iterator previous;
1644
if ((*fx_list.begin())==effect) return;
1646
for (previous=i=fx_list.begin(); i != fx_list.end(); i++) {
1647
if ((*i) == effect) {
1655
pthread_mutex_lock(&render_lock);
1656
fx_list.remove(effect);
1657
fx_list.insert(previous, effect);
1658
pthread_mutex_unlock(&render_lock);
1660
vg_move_fx_panel_up(effect->get_panel_widget(), this);
1666
void vtt_class :: effect_down(vtt_fx *effect)
1668
list <vtt_fx *> :: iterator i;
1673
for (i=fx_list.begin(); i != fx_list.end(); i++) {
1674
if ((*i) == effect) {
1680
if ((ok) && (i!=fx_list.end())) {
1682
if (i==fx_list.end()) return;
1685
pthread_mutex_lock(&render_lock);
1686
fx_list.remove(effect);
1688
fx_list.insert(i, effect);
1689
vg_move_fx_panel_down(effect->get_panel_widget(), this);
1690
pthread_mutex_unlock(&render_lock);
1696
void vtt_class :: effect_remove(vtt_fx_ladspa *effect)
1698
pthread_mutex_lock(&render_lock);
1699
fx_list.remove(effect);
1700
pthread_mutex_unlock(&render_lock);
1705
extern void gui_hide_control_panel(vtt_class *vtt, bool hide);
1706
extern void gui_hide_audio_panel(vtt_class *vtt, bool hide);
1708
void vtt_class :: hide_audio(bool hide) {
1710
gui_hide_audio_panel(this, hide);
1713
void vtt_class :: hide_control(bool hide) {
1714
control_hidden=hide;
1715
gui_hide_control_panel(this, hide);
1718
void vtt_class :: set_sample_rate(int samplerate) {
1719
list <vtt_class *> :: iterator vtt;
1720
double sr=(double) samplerate;
1722
last_sample_rate=samplerate;
1724
for (vtt=main_list.begin(); vtt!=main_list.end() ; vtt++) {
1725
if ((*vtt)->audiofile) {
1726
double file_rate=(*vtt)->audiofile->get_sample_rate();
1727
(*vtt)->audiofile_pitch_correction=file_rate/sr;
1729
(*vtt)->audiofile_pitch_correction=1.0;
1731
(*vtt)->recalc_pitch();
1734
int no_samples=(int) (sr*0.001); // Forcing 1 ms blocksize
1736
set_mix_buffer_size(no_samples);
1739
void vtt_class :: adjust_to_master_pitch(int master_cycles, int cycles, bool create_event) {
1740
if (!sync_master) return;
1741
if (this==sync_master) return;
1742
if (!sync_master->audiofile) return;
1743
if (!audiofile) return;
1745
double master_time=((double) master_cycles)/sync_master->rel_pitch*sync_master->audiofile->get_no_samples()/((double) sync_master->audiofile->get_sample_rate());
1746
double my_rel_pitch=((audiofile->get_no_samples()/((double) audiofile->get_sample_rate()))*((double) cycles))/master_time;
1749
sp_pitch.do_exec(my_rel_pitch);
1750
sp_pitch.record_value(my_rel_pitch);
1752
sp_pitch.do_exec(my_rel_pitch);
1755
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());
1757
sp_pitch.update_graphics();