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 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"
57 #include "tX_endian.h"
59 #include "tX_global.h"
61 #include "tX_dialog.h"
65 #include "tX_ladspa.h"
67 #include "tX_engine.h"
69 #ifdef CREATE_BENCHMARK
77 /* Function to test if multimedia instructions are supported...
82 /* Returns 1 if MMX instructions are supported,
83 3 if Cyrix MMX and Extended MMX instructions are supported
84 5 if AMD MMX and 3DNow! instructions are supported
85 0 if hardware does not support any of these
87 register int rval = 0;
89 __asm__ __volatile__ (
90 /* See if CPUID instruction is supported ... */
91 /* ... Get copies of EFLAGS into eax and ecx */
94 "movl %%eax, %%ecx\n\t"
96 /* ... Toggle the ID bit in one copy and store */
97 /* to the EFLAGS reg */
98 "xorl $0x200000, %%eax\n\t"
102 /* ... Get the (hopefully modified) EFLAGS */
106 /* ... Compare and test result */
107 "xorl %%eax, %%ecx\n\t"
108 "testl $0x200000, %%ecx\n\t"
109 "jz NotSupported1\n\t" /* CPUID not supported */
112 /* Get standard CPUID information, and
113 go to a specific vendor section */
117 /* Check for Intel */
118 "cmpl $0x756e6547, %%ebx\n\t"
120 "cmpl $0x49656e69, %%edx\n\t"
122 "cmpl $0x6c65746e, %%ecx\n"
128 "cmpl $0x68747541, %%ebx\n\t"
130 "cmpl $0x69746e65, %%edx\n\t"
132 "cmpl $0x444d4163, %%ecx\n"
136 /* Check for Cyrix */
138 "cmpl $0x69727943, %%ebx\n\t"
139 "jne NotSupported2\n\t"
140 "cmpl $0x736e4978, %%edx\n\t"
141 "jne NotSupported3\n\t"
142 "cmpl $0x64616574, %%ecx\n\t"
143 "jne NotSupported4\n\t"
144 /* Drop through to Cyrix... */
148 /* See if extended CPUID level 80000001 is supported */
149 /* The value of CPUID/80000001 for the 6x86MX is undefined
150 according to the Cyrix CPU Detection Guide (Preliminary
151 Rev. 1.01 table 1), so we'll check the value of eax for
152 CPUID/0 to see if standard CPUID level 2 is supported.
153 According to the table, the only CPU which supports level
154 2 is also the only one which supports extended CPUID levels.
156 "cmpl $0x2, %%eax\n\t"
157 "jne MMXtest\n\t" /* Use standard CPUID instead */
159 /* Extended CPUID supported (in theory), so get extended
161 "movl $0x80000001, %%eax\n\t"
163 "testl $0x00800000, %%eax\n\t" /* Test for MMX */
164 "jz NotSupported5\n\t" /* MMX not supported */
165 "testl $0x01000000, %%eax\n\t" /* Test for Ext'd MMX */
166 "jnz EMMXSupported\n\t"
167 "movl $1, %0\n\n\t" /* MMX Supported */
170 "movl $3, %0\n\n\t" /* EMMX and MMX Supported */
177 /* See if extended CPUID is supported */
178 "movl $0x80000000, %%eax\n\t"
180 "cmpl $0x80000000, %%eax\n\t"
181 "jl MMXtest\n\t" /* Use standard CPUID instead */
183 /* Extended CPUID supported, so get extended features */
184 "movl $0x80000001, %%eax\n\t"
186 "testl $0x00800000, %%edx\n\t" /* Test for MMX */
187 "jz NotSupported6\n\t" /* MMX not supported */
188 "testl $0x80000000, %%edx\n\t" /* Test for 3DNow! */
189 "jnz ThreeDNowSupported\n\t"
190 "movl $1, %0\n\n\t" /* MMX Supported */
192 "ThreeDNowSupported:\n\t"
193 "movl $5, %0\n\n\t" /* 3DNow! and MMX Supported */
204 "testl $0x00800000, %%edx\n\t" /* Test for MMX */
205 "jz NotSupported7\n\t" /* MMX Not supported */
206 "movl $1, %0\n\n\t" /* MMX Supported */
209 /* Nothing supported */
210 "\nNotSupported1:\n\t"
211 "#movl $101, %0\n\n\t"
212 "\nNotSupported2:\n\t"
213 "#movl $102, %0\n\n\t"
214 "\nNotSupported3:\n\t"
215 "#movl $103, %0\n\n\t"
216 "\nNotSupported4:\n\t"
217 "#movl $104, %0\n\n\t"
218 "\nNotSupported5:\n\t"
219 "#movl $105, %0\n\n\t"
220 "\nNotSupported6:\n\t"
221 "#movl $106, %0\n\n\t"
222 "\nNotSupported7:\n\t"
223 "#movl $107, %0\n\n\t"
229 : "eax", "ebx", "ecx", "edx"
243 time=g_timer_elapsed(my_time, &ms);
246 gtk_idle_remove(idle_tag);
258 usage: terminatorX [options]n\
260 -h, --help Display help info\n\
261 -f, --file Load saved terminatorX set file\n\
262 -r, --rc-file [file] Load alternate rc file\n\
263 -d, --dont-save Do not save settings at exit\n\
264 -s, --std-out Use stdout for sound output\n\
265 --device=[output device] Use alternate device for sound output\n\
268 -n, --no-gui Run terminatorX with no GUI\n\
269 -m, --midi-in [file] Use [file] for midi input\n\
270 -o, --midi-out [file] Use [file] for midi input\n\
271 -s, --std-out Use stdout for sound output\n\
277 int parse_args(int *argc, char **argv)
279 // pass over argv once to see if we need to load an alternate_rc file
280 for (int i = 1 ; i != *argc ; ++i )
282 if ((strcmp(argv[i], "-r") == 0) || (strcmp(argv[i], "--rc-file") == 0))
287 fprintf(stderr, "tX: Loading alternate rc file %s\n", argv[i]);
288 globals.alternate_rc = argv[i];
299 // load up the global values
302 // default the flag options, or they'll be set from last execution... (think globals.no_gui ;)
304 globals.alternate_rc = 0;
305 globals.store_globals = 1;
306 globals.startup_set = 0;
308 // then pass over again, this time setting passed values
309 for (int i = 1 ; i < *argc ; ++i )
311 if ((strcmp(argv[i], "-f") == 0) || (strcmp(argv[i], "--file") == 0))
314 globals.startup_set = argv[i];
316 else if (((strcmp(argv[i], "-r") == 0) || (strcmp(argv[i], "--rc-file") == 0)) && (argv[i+1]))
319 globals.alternate_rc = argv[i];
321 else if ((strcmp(argv[i], "-d") == 0) || (strcmp(argv[i], "--dont-save") == 0))
323 fprintf(stderr, "tX: Do not save settings on exit\n");
324 globals.store_globals = 0;
327 else if ((strcmp(argv[i], "-s") == 0) || (strcmp(argv[i], "--std-out") == 0))
329 globals.use_stdout_cmdline = 1;
330 globals.use_stdout = 1;
332 else if ((strncmp(argv[i], "--device",8) == 0))
334 if (strlen(argv[i]+9)<=PATH_MAX)
335 strcpy(globals.audio_device,argv[i]+9);
343 else if ((strcmp(argv[i], "-m") == 0) || (strcmp(argv[i], "--midi-in") == 0))
346 else if ((strcmp(argv[i], "-s") == 0) || (strcmp(argv[i], "--std-out") == 0))
349 else if ((strcmp(argv[i], "-n") == 0) || (strcmp(argv[i], "--no-gui") == 0))
352 fprintf(stderr, "tX: Run without a GUI\n");
364 int main(int argc, char **argv)
368 fprintf(stderr, "%s - Copyright (C) 1999-2002 by Alexander König\n", VERSIONSTRING);
369 fprintf(stderr, "terminatorX comes with ABSOLUTELY NO WARRANTY - for details read the license.\n");
371 engine=new tX_engine();
374 if (tx_mm_support()!=5)
376 printf("3DNow! not detected. Giving up.\n");
380 printf("3DNow! accelerations available.\n");
382 // gtk_set_locale ();
383 gtk_init (&argc, &argv);
385 /* gtk_rc_file=fopen(TX_GTKRC, "r");
388 fprintf (stderr, "Using terminatorX gtkrc.\n");
390 gtk_rc_parse(TX_GTKRC);
393 parse_args(&argc, argv);
395 if (globals.show_nag)
399 my_time=g_timer_new();
400 g_timer_start(my_time);
402 idle_tag=gtk_idle_add((GtkFunction)idle, NULL);
405 LADSPA_Plugin :: init();
406 // LADSPA_Plugin :: status();
408 create_mastergui(globals.width, globals.height);
410 if (!globals.show_nag) display_mastergui();
412 if (globals.startup_set)
414 while (gtk_events_pending()) gtk_main_iteration(); gdk_flush();
415 load_tt_part(globals.startup_set);
418 #ifndef CREATE_BENCHMARK
428 fprintf(stderr, "Have a nice life.\n");
430 gtk_widget_hide(main_window);
431 while (gtk_events_pending()) gtk_main_iteration(); gdk_flush();
434 vtt_class::set_mix_buffer_size(globals.true_block_size);
435 printf("\n* BENCHMARKING *\nBlocksize is %i samples.\n", globals.true_block_size);
437 GTimer *bench_time = g_timer_new();
441 list <vtt_class *> :: iterator vtt;
443 for (vtt=vtt_class::main_list.begin(); vtt!=vtt_class::main_list.end(); vtt++)
445 if ((*vtt)->autotrigger) (*vtt)->trigger();
449 g_timer_start(bench_time);
450 for (int i=0; i<BENCH_CYCLES; i++)
452 vtt_class::render_all_turntables();
454 g_timer_stop(bench_time);
455 res=g_timer_elapsed(bench_time, µs);
457 ratio=((double) BENCH_CYCLES)/res;
458 printf ("Rendered %i blocks in %f secons,\n=> %f blocks per second.\n\n", (long) BENCH_CYCLES, res, ratio);