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 contains the main() function. All the initializing
26
19 Mar 1999: Applied a patch by Andrew C. Bul+hac?k (eMail: acb@zikzak.net)
27
that fixes wavfile reading routine for the overreading bug.
29
20 Mar 1999: Big endian support.
31
23 Mar 1999: display of new keys (<-, ->)
33
4 October 1999: Rewrite ;) - back to C++
36
#define TX_GTKRC "/usr/share/themes/terminatorX/gtk/gtkrc"
38
#define BENCH_CYCLES 100000
41
#include "tX_mastergui.h"
53
#include "tX_endian.h"
55
#include "tX_global.h"
56
#include "tX_audiodevice.h"
58
#include "tX_dialog.h"
63
#include "tX_ladspa.h"
64
#include "tX_ladspa_class.h"
65
#include "tX_engine.h"
66
#include "tX_capabilities.h"
68
#ifdef CREATE_BENCHMARK
74
#include <sys/types.h>
81
if ((!tX_jack_client::get_instance()) && (globals.audiodevice_type==JACK)) {
82
tx_note("Couldn't connect to JACK server - JACK output not available.\n\nIf you want to use JACK, ensure the JACK daemon is running before you start terminatorX.", true);
87
static bool timesup=false;
89
gboolean timeout(void *)
99
usage: terminatorX [options]n\
101
-h, --help Display help info\n\
102
-f, --file Load saved terminatorX set file\n\
103
-r, --rc-file [file] Load alternate rc file\n\
104
-d, --dont-save Do not save settings at exit\n\
105
-s, --std-out Use stdout for sound output\n\
106
--device=[output device] Use alternate device for sound output\n\
110
int parse_args(int *argc, char **argv)
112
// pass over argv once to see if we need to load an alternate_rc file
113
for (int i = 1 ; i != *argc ; ++i ) {
114
if ((strcmp(argv[i], "-r") == 0) || (strcmp(argv[i], "--rc-file") == 0)) {
117
fprintf(stderr, "tX: Loading alternate rc file %s\n", argv[i]);
118
globals.alternate_rc = argv[i];
127
// load up the global values
130
// default the flag options, or they'll be set from last execution... (think globals.no_gui ;)
132
globals.alternate_rc = 0;
133
globals.store_globals = 1;
134
globals.startup_set = 0;
136
// then pass over again, this time setting passed values
137
for (int i = 1 ; i < *argc ; ++i ) {
138
if ((strcmp(argv[i], "-f") == 0) || (strcmp(argv[i], "--file") == 0)) {
140
globals.startup_set = argv[i];
141
} else if (((strcmp(argv[i], "-r") == 0) || (strcmp(argv[i], "--rc-file") == 0)) && (argv[i+1])) {
143
globals.alternate_rc = argv[i];
144
} else if ((strcmp(argv[i], "-d") == 0) || (strcmp(argv[i], "--dont-save") == 0)) {
145
fprintf(stderr, "tX: Do not save settings on exit\n");
146
globals.store_globals = 0;
148
} else if ((strcmp(argv[i], "-s") == 0) || (strcmp(argv[i], "--std-out") == 0)) {
149
globals.use_stdout_cmdline = 1;
150
globals.use_stdout = 1;
151
} else if ((strncmp(argv[i], "--device",8) == 0)) {
152
if (strlen(argv[i]+9)<=PATH_MAX)
153
strcpy(globals.oss_device,argv[i]+9);
166
void checkenv(const char *name)
173
length=strlen(value);
175
strnlen requires extra macros...
176
length=strnlen(value, PATH_MAX+1);
179
if (length>=PATH_MAX) {
180
tX_error("Your \"%s\" environment variable seems malicious (%i chars).", name, length);
181
tX_error("Please correct that and restart terminatorX.");
187
int main(int argc, char **argv)
189
fprintf(stderr, "%s - Copyright (C) 1999-2003 by Alexander K�nig\n", VERSIONSTRING);
190
fprintf(stderr, "terminatorX comes with ABSOLUTELY NO WARRANTY - for details read the license.\n");
192
#ifdef USE_CAPABILITIES
194
if (prctl(PR_SET_KEEPCAPS, 1, -1, -1, -1)) {
195
tX_error("failed to keep capabilites.");
197
set_nice_capability(CAP_PERMITTED);
200
if ((!geteuid()) && (getuid() != geteuid())) {
201
tX_debug("main() - capabilites set, dropping root privileges.");
203
int result=setuid(getuid());
206
tX_error("main() Panic: can't drop root privileges.");
211
set_nice_capability(CAP_EFFECTIVE);
215
checkenv("XLOCALEDIR");
217
#ifndef USE_CAPABILITIES
218
/* If we're not using capabilities we're still
219
running suid-root here. So we get rid of root
220
before doing anything esle.
222
tX_engine *engine=tX_engine::get_instance();
225
gtk_init (&argc, &argv);
228
parse_args(&argc, argv); // loads settings
230
if (globals.show_nag) {
232
g_timeout_add(2000, (GSourceFunc) timeout, NULL);
235
#ifdef USE_CAPABILITIES
236
/* If we have capabilities it's save to
237
first read the config and then create
240
tX_engine *engine=tX_engine::get_instance();
243
LADSPA_Class::init();
244
LADSPA_Plugin::init();
246
tX_jack_client::init();
250
tX_debug("main() GUI thread is p:%i, t:%i and has policy %i.", getpid(), (int) pthread_self(), sched_getscheduler(getpid()));
253
create_mastergui(globals.width, globals.height);
255
if (globals.show_nag) {
257
while (gtk_events_pending()) gtk_main_iteration();
269
if (globals.startup_set) {
270
while (gtk_events_pending()) gtk_main_iteration(); gdk_flush();
271
tX_cursor::set_cursor(tX_cursor::WAIT_CURSOR);
272
load_tt_part(globals.startup_set);
273
tX_cursor::reset_cursor();
275
#ifdef USE_ALSA_MIDI_IN
276
if (globals.auto_assign_midi) tX_midiin::auto_assign_midi_mappings(NULL, NULL);
280
#ifndef CREATE_BENCHMARK
287
if (tX_jack_client::get_instance()) {
288
delete tX_jack_client::get_instance();
292
fprintf(stderr, "Have a nice life.\n");
293
#else // CREATE_BENCHMARK
294
gtk_widget_hide(main_window);
295
while (gtk_events_pending()) gtk_main_iteration(); gdk_flush();
298
vtt_class::set_sample_rate(48000);
300
printf("\n* BENCHMARKING *\n");
302
GTimer *bench_time = g_timer_new();
306
list <vtt_class *> :: iterator vtt;
308
for (vtt=vtt_class::main_list.begin(); vtt!=vtt_class::main_list.end(); vtt++) {
309
if ((*vtt)->autotrigger) (*vtt)->trigger();
313
g_timer_start(bench_time);
315
for (int i=0; i<BENCH_CYCLES; i++) {
316
vtt_class::render_all_turntables();
318
g_timer_stop(bench_time);
319
res=g_timer_elapsed(bench_time, µs);
321
ratio=((double) BENCH_CYCLES)/res;
322
printf ("Rendered %i blocks in %f secons,\n=> %f blocks per second.\n\n", (long) BENCH_CYCLES, res, ratio);
323
#endif // CREATE_BENCHMARK