1 /*
2 argdecode.c:
3
4 Copyright (C) 1998-2013 John ffitch, Victor Lazzarini
5
6 This file is part of Csound.
7
8 The Csound Library is free software; you can redistribute it
9 and/or modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version.
12
13 Csound is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public
19 License along with Csound; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 02110-1301 USA
22 */
23 #include "csoundCore.h" /* ARGDECODE.C */
24 #include "soundio.h"
25 #include "new_opts.h"
26 #include "csmodule.h"
27 #include "corfile.h"
28 #include <ctype.h>
29
30 static void list_audio_devices(CSOUND *csound, int output);
31 static void list_midi_devices(CSOUND *csound, int output);
32 extern void strset_option(CSOUND *csound, char *s); /* from str_ops.c */
33 extern void print_csound_version(CSOUND* csound);
34
35 #define FIND(MSG) if (*s == '\0') \
36 if (UNLIKELY(!(--argc) || (((s = *++argv) != NULL) && *s == '-'))) \
37 dieu(csound, MSG);
38
39 #define STDINASSIGN_SNDFILE 1
40 #define STDINASSIGN_LINEIN 2
41 #define STDINASSIGN_MIDIFILE 4
42 #define STDINASSIGN_MIDIDEV 8
43
44 #define STDOUTASSIGN_SNDFILE 1
45 #define STDOUTASSIGN_MIDIOUT 2
46
47 /* IV - Feb 19 2005 */
48
49 #ifdef EXPERIMENTAL
50 static FILE *logFile = NULL; /* NOT THREAD SAFE */
51
msg_callback(CSOUND * csound,int attr,const char * format,va_list args)52 void msg_callback(CSOUND *csound,
53 int attr, const char *format, va_list args)
54 {
55 (void) csound;
56 if ((attr & CSOUNDMSG_TYPE_MASK) != CSOUNDMSG_REALTIME) {
57 vfprintf(logFile, format, args);
58 fflush(logFile);
59 return;
60 }
61 #if defined(WIN32) || defined(MAC)
62 switch (attr & CSOUNDMSG_TYPE_MASK) {
63 case CSOUNDMSG_ERROR:
64 case CSOUNDMSG_WARNING:
65 case CSOUNDMSG_REALTIME:
66 break;
67 default:
68 vfprintf(logFile, format, args);
69 return;
70 }
71 #endif
72
73 vfprintf(stderr, format, args);
74 }
75
nomsg_callback(CSOUND * csound,int attr,const char * format,va_list args)76 void nomsg_callback(CSOUND *csound,
77 int attr, const char *format, va_list args){ return; }
78
do_logging(char * s)79 void do_logging(char *s)
80 {
81 int nomessages = 0;
82 if (logFile) return;
83 if (!strcmp(s, "NULL") || !strcmp(s, "null"))
84 nomessages = 1;
85 else if ((logFile = fopen(s, "w")) == NULL) {
86 fprintf(stderr, Str("Error opening log file '%s': %s\n"),
87 s, strerror(errno));
88 exit(1);
89 }
90 /* if logging to file, set message callback */
91 if (logFile != NULL)
92 csoundSetDefaultMessageCallback(msg_callback);
93 else if (nomessages)
94 csoundSetDefaultMessageCallback(nomsg_callback);
95 }
96
end_logging(void)97 void end_logging(void)
98 {
99 if (logFile != NULL)
100 fclose(logFile);
101 }
102 #else
103 #define do_logging(x) {}
104 #endif
105
set_stdin_assign(CSOUND * csound,int type,int state)106 static inline void set_stdin_assign(CSOUND *csound, int type, int state)
107 {
108 if (state)
109 csound->stdin_assign_flg |= type;
110 else
111 csound->stdin_assign_flg &= (~type);
112 }
113
set_stdout_assign(CSOUND * csound,int type,int state)114 static inline void set_stdout_assign(CSOUND *csound, int type, int state)
115 {
116 if (state)
117 csound->stdout_assign_flg |= type;
118 else
119 csound->stdout_assign_flg &= (~type);
120 }
121
122 /* IV - Feb 19 2005 */
123 static const char *shortUsageList[] = {
124 Str_noop("--help print long usage options"),
125 Str_noop("--version print version details"),
126 Str_noop("-U unam run utility program unam"),
127 Str_noop("-C use Cscore processing of scorefile"),
128 Str_noop("-j N use N threads in performance"),
129 Str_noop("-I I-time only orch run"),
130 Str_noop("-n no sound onto disk"),
131 Str_noop("-i fnam sound input filename"),
132 Str_noop("-o fnam sound output filename"),
133 Str_noop("-b N sample frames (or -kprds) per software sound I/O buffer"),
134 Str_noop("-B N samples per hardware sound I/O buffer"),
135 Str_noop("-A create an AIFF format output soundfile"),
136 Str_noop("-W create a WAV format output soundfile"),
137 Str_noop("-J create an IRCAM format output soundfile"),
138 Str_noop("-h no header on output soundfile"),
139 Str_noop("-c 8-bit signed_char sound samples"),
140 #ifdef never
141 Str_noop("-a alaw sound samples"),
142 #endif
143 Str_noop("-8 8-bit unsigned_char sound samples"),
144 Str_noop("-u ulaw sound samples"),
145 Str_noop("-s short_int sound samples"),
146 Str_noop("-l long_int sound samples"),
147 Str_noop("-f float sound samples"),
148 Str_noop("-3 24bit sound samples"),
149 Str_noop("-r N orchestra srate override"),
150 Str_noop("-k N orchestra krate override"),
151 Str_noop("-K do not generate PEAK chunks"),
152 Str_noop("-v verbose orch translation"),
153 Str_noop("-m N tty message level. Sum of:"),
154 Str_noop(" 1=note amps, 2=out-of-range msg, 4=warnings"),
155 Str_noop(" 0/32/64/96=note amp format (raw,dB,colors)"),
156 Str_noop(" 128=print benchmark information"),
157 Str_noop("-d suppress all displays"),
158 Str_noop("-g suppress graphics, use ascii displays"),
159 Str_noop("-G suppress graphics, use Postscript displays"),
160 Str_noop("-x fnam extract from score.srt using extract file 'fnam'"),
161 Str_noop("-t N use uninterpreted beats of the score, "
162 "initially at tempo N"),
163 Str_noop("-t 0 use score.srt for sorted score rather than a temporary"),
164 Str_noop("-L dnam read Line-oriented realtime score events from "
165 "device 'dnam'"),
166 Str_noop("-M dnam read MIDI realtime events from device 'dnam'"),
167 Str_noop("-F fnam read MIDIfile event stream from file 'fnam'"),
168 /* Str_noop("-P N MIDI sustain pedal threshold (0 - 128)"), */
169 Str_noop("-R continually rewrite header while writing soundfile "
170 "(WAV/AIFF)"),
171 Str_noop("-H# print heartbeat style 1, 2 or 3 at each soundfile write"),
172 Str_noop("-N notify (ring the bell) when score or miditrack is done"),
173 Str_noop("-T terminate the performance when miditrack is done"),
174 Str_noop("-D defer GEN01 soundfile loads until performance time"),
175 Str_noop("-Q dnam select MIDI output device"),
176 Str_noop("-z list opcodes in this version"),
177 Str_noop("-Z dither output"),
178 #if defined(LINUX)
179 Str_noop("--sched set real-time priority and lock memory"),
180 Str_noop(" (requires -d and real time audio (-iadc/-odac))"),
181 Str_noop("--sched=N set specified scheduling priority, and lock memory"),
182 Str_noop(" (requires -d and real time audio (-iadc/-odac))"),
183 #endif
184 NULL
185 };
186
187 static const char *longUsageList[] = {
188 "--format={wav,aiff,au,raw,paf,svx,nist,voc,ircam,w64,mat4,mat5",
189 " pvf,xi,htk,sds,avr,wavex,sd2,flac,caf,wve,ogg,mpc2k,rf64}",
190 "--format={alaw,ulaw,schar,uchar,float,double,short,long,24bit,vorbis}",
191 Str_noop(" Set output file format"),
192 Str_noop("--aiff set AIFF format"),
193 Str_noop("--au set AU format"),
194 Str_noop("--wave set WAV format"),
195 Str_noop("--ircam set IRCAM format"),
196 Str_noop("--ogg set OGG/VORBIS format"),
197 Str_noop("--noheader raw format"),
198 Str_noop("--nopeaks do not write peak information"),
199 " ",
200 Str_noop("--displays use graphic displays"),
201 Str_noop("--nodisplays suppress all displays"),
202 Str_noop("--asciidisplay suppress graphics, use ascii displays"),
203 Str_noop("--postscriptdisplay suppress graphics, use Postscript displays"),
204 " ",
205 Str_noop("--defer-gen1 defer GEN01 soundfile loads until "
206 "performance time"),
207 Str_noop("--iobufsamps=N sample frames (or -kprds) per software "
208 "sound I/O buffer"),
209 Str_noop("--hardwarebufsamps=N samples per hardware sound I/O buffer"),
210 Str_noop("--cscore use Cscore processing of scorefile"),
211 Str_noop("--orc use orchfile without scorefile"),
212 " ",
213 Str_noop("--midifile=FNAME read MIDIfile event stream from file"),
214 Str_noop("--midioutfile=FNAME write MIDI output to file FNAME"),
215 Str_noop("--midi-device=FNAME read MIDI realtime events from device"),
216 Str_noop("--terminate-on-midi terminate the performance when miditrack "
217 "is done"),
218 " ",
219 Str_noop("--heartbeat=N print a heartbeat style 1, 2 or 3 at "
220 "each soundfile write"),
221 Str_noop("--notify notify (ring the bell) when score or "
222 "miditrack is done"),
223 Str_noop("--rewrite continually rewrite header while writing "
224 "soundfile (WAV/AIFF)"),
225 " ",
226 Str_noop("--input=FNAME sound input filename"),
227 Str_noop("--output=FNAME sound output filename"),
228 Str_noop("--logfile=FNAME log output to file"),
229 " ",
230 Str_noop("--nosound no sound onto disk or device"),
231 Str_noop("--tempo=N use uninterpreted beats of the score, "
232 "initially at tempo N"),
233 Str_noop("--i-only I-time only orch run"),
234 Str_noop("--syntax-check-only stop after checking orchestra and "
235 "score syntax"),
236 Str_noop("--control-rate=N orchestra krate override"),
237 Str_noop("--sample-rate=N orchestra srate override"),
238 Str_noop("--score-in=FNAME read line-oriented realtime score events "
239 "from device"),
240 Str_noop("--messagelevel=N tty message level, sum of:"),
241 Str_noop("--messageolevel=O tty message level in octal, of:"),
242 Str_noop(" 1=note amps, 2=out-of-range msg, 4=warnings,"),
243 Str_noop(" 0/32/64/96=note amp format (raw,dB,colors),"),
244 Str_noop(" 128=print benchmark information"),
245 " ",
246 Str_noop("--m-amps=[01] messages on note amps"),
247 Str_noop("--m-range=[01] messages on range errors"),
248 Str_noop("--m-warnings=[01] mesage on warnings"),
249 Str_noop("--m-raw=[01] raw amp messages"),
250 Str_noop("--m-dB=[01] amp messages in dB"),
251 Str_noop("--m-colours=[01] colour amp messages"),
252 Str_noop("--m-benchmarks=[01] print benchmark information"),
253 Str_noop("--csd-line-nums=[01] controls how error line numbers are printed:"),
254 Str_noop(" 1=use CSD line #s (default), 0=use "
255 "ORC/SCO-relative line #s"),
256 Str_noop("--extract-score=FNAME extract from score.srt using extract file"),
257 Str_noop("--keep-sorted-score"),
258 Str_noop("--keep-sorted-score=FNAME"),
259 Str_noop("--simple-sorted-score"),
260 Str_noop("--simple-sorted-score=FNAME"),
261 Str_noop("--env:NAME=VALUE set environment variable NAME to VALUE"),
262 Str_noop("--env:NAME+=VALUE append VALUE to environment variable NAME"),
263 Str_noop("--strsetN=VALUE set strset table at index N to VALUE"),
264 Str_noop("--utility=NAME run utility program"),
265 Str_noop("--verbose verbose orch translation"),
266 Str_noop("--list-opcodes list opcodes in this version"),
267 Str_noop("--list-opcodesN list opcodes in style N in this version"),
268 Str_noop("--dither dither output"),
269 Str_noop("--dither-triangular dither output with triangular distribution"),
270 Str_noop("--dither-uniform dither output with rectanular distribution"),
271 Str_noop("--sched set real-time scheduling priority and "
272 "lock memory"),
273 Str_noop("--sched=N set priority to N and lock memory"),
274 Str_noop("--opcode-dir=DIR load all plugins from DIR"),
275 Str_noop("--opcode-lib=NAMES dynamic libraries to load"),
276 Str_noop("--opcode-omit=NAMES dynamic libraries not to load"),
277 Str_noop("--omacro:XXX=YYY set orchestra macro XXX to value YYY"),
278 Str_noop("--smacro:XXX=YYY set score macro XXX to value YYY"),
279 Str_noop("--midi-key=N route MIDI note on message"),
280 Str_noop(" key number to pfield N as "
281 "MIDI value [0-127]"),
282 Str_noop("--midi-key-cps=N route MIDI note on message"),
283 Str_noop(" key number to pfield N as cycles per second"),
284 Str_noop("--midi-key-oct=N route MIDI note on message"),
285 Str_noop(" key number to pfield N as linear octave"),
286 Str_noop("--midi-key-pch=N route MIDI note on message"),
287 Str_noop(" key number to pfield N as oct.pch"),
288 Str_noop("--midi-velocity=N route MIDI note on message"),
289 Str_noop(" velocity number to pfield N as MIDI "
290 "value [0-127]"),
291 Str_noop("--midi-velocity-amp=N route MIDI note on message"),
292 Str_noop(" velocity number to pfield N as amplitude"),
293 Str_noop("--no-default-paths turn off relative paths from CSD/ORC/SCO"),
294 Str_noop("--sample-accurate use sample-accurate timing of score events"),
295 Str_noop("--realtime realtime priority mode"),
296 Str_noop("--nchnls=N override number of audio channels"),
297 Str_noop("--nchnls_i=N override number of input audio channels"),
298 Str_noop("--0dbfs=N override 0dbfs (max positive signal amplitude)"),
299 Str_noop("--sinesize length of internal sine table"),
300 Str_noop("--daemon daemon mode: do not exit if CSD/orchestra is "
301 "not given, is empty or does not compile"),
302 Str_noop("--port=N listen to UDP port N for instruments/orchestra "
303 "code (implies --daemon)"),
304 Str_noop("--vbr-quality=Ft set quality of variable bit-rate compression"),
305 Str_noop("--devices[=in|out] list available audio devices and exit"),
306 Str_noop("--midi-devices[=in|out] list available MIDI devices and exit"),
307 Str_noop("--get-system-sr print system sr and exit, requires realtime\n"
308 " audio output (e.g. -odac) to be defined first)"),
309 Str_noop("--use-system-sr print system sr and use realtime audio\n"
310 " output (e.g. -odac) to be defined first"),
311 Str_noop("--ksmps=N override ksmps"),
312 Str_noop("--fftlib=N actual FFT lib to use (FFTLIB=0, "
313 "PFFFT = 1, vDSP =2)"),
314 Str_noop("--udp-echo echo UDP commands on terminal"),
315 Str_noop("--aft-zero set aftertouch to zero, not 127 (default)"),
316 " ",
317 Str_noop("--help long help"),
318 NULL
319 };
320
321 /* IV - Feb 19 2005 */
print_short_usage(CSOUND * csound)322 void print_short_usage(CSOUND *csound)
323 {
324 char buf[256];
325 int i;
326 i = -1;
327 while (shortUsageList[++i] != NULL) {
328 snprintf(buf, 256, "%s\n", shortUsageList[i]);
329 csound->Message(csound, "%s", Str(buf));
330 }
331 csound->Message(csound,
332 Str("flag defaults: csound -s -otest -b%d -B%d -m%d\n\n"),
333 IOBUFSAMPS, IODACSAMPS, csound->oparms->msglevel);
334 }
335
longusage(CSOUND * p)336 static void longusage(CSOUND *p)
337 {
338 const char **sp;
339 p->Message(p, Str("Usage: csound [-flags] orchfile scorefile\n"));
340 p->Message(p, Str("Legal flags are:\n"));
341 p->Message(p, Str("Long format:\n\n"));
342 for (sp = &(longUsageList[0]); *sp != NULL; sp++)
343 p->Message(p, "%s\n", Str(*sp));
344 dump_cfg_variables(p);
345 p->Message(p, Str("\nShort format:\n\n"));
346 print_short_usage(p);
347 }
348
dieu(CSOUND * csound,char * s,...)349 CS_NORETURN void dieu(CSOUND *csound, char *s, ...)
350 {
351 va_list args;
352
353 csound->Message(csound,Str("Usage: csound [-flags] orchfile scorefile\n"));
354 csound->Message(csound,Str("Legal flags are:\n"));
355 print_short_usage(csound);
356 va_start(args, s);
357 csound->ErrMsgV(csound, Str("Csound Command ERROR: "), s, args);
358 va_end(args);
359 //// FIXME This code makes no sense
360 /* if (csound->info_message_request == 0) { */
361 /* csound->info_message_request = 0; */
362 /* csound->LongJmp(csound, 1); */
363 /* } */
364 //Added longjump -- JPff
365 csound->LongJmp(csound, 1);
366 }
367
set_output_format(OPARMS * O,char c)368 void set_output_format(OPARMS *O, char c)
369 {
370 switch (c) {
371 case 'a':
372 O->outformat = AE_ALAW; /* a-law soundfile */
373 break;
374
375 case 'c':
376 O->outformat = AE_CHAR; /* signed 8-bit soundfile */
377 break;
378
379 case '8':
380 O->outformat = AE_UNCH; /* unsigned 8-bit soundfile */
381 break;
382
383 case 'f':
384 O->outformat = AE_FLOAT; /* float soundfile */
385 break;
386
387 case 'd':
388 O->outformat = AE_DOUBLE; /* double soundfile */
389 break;
390
391 case 's':
392 O->outformat = AE_SHORT; /* short_int soundfile*/
393 break;
394
395 case 'l':
396 O->outformat = AE_LONG; /* long_int soundfile */
397 break;
398
399 case 'u':
400 O->outformat = AE_ULAW; /* mu-law soundfile */
401 break;
402
403 case '3':
404 O->outformat = AE_24INT; /* 24bit packed soundfile*/
405 break;
406
407 case 'e':
408 O->outformat = AE_FLOAT; /* float soundfile (for rescaling) */
409 break;
410
411 case 'v':
412 O->outformat = AE_VORBIS; /* Xiph Vorbis encoding */
413 break;
414
415 default:
416 return; /* do nothing */
417 };
418 }
419
420
421 typedef struct {
422 char *longformat;
423 char shortformat;
424 } SAMPLE_FORMAT_ENTRY;
425
426 static const SAMPLE_FORMAT_ENTRY sample_format_map[] = {
427 { "alaw", 'a' }, { "schar", 'c' }, { "uchar", '8' },
428 { "float", 'f' }, { "double", 'd' }, { "long", 'l' },
429 { "short", 's' }, { "ulaw", 'u' }, { "24bit", '3' },
430 { "vorbis", 'v' }, { NULL, '\0' }
431 };
432
get_output_format(OPARMS * O)433 const char* get_output_format(OPARMS *O)
434 {
435 int i = 0;
436 char c;
437 switch (O->outformat) {
438 case AE_ALAW:
439 c = 'a';
440 break;
441 case AE_CHAR:
442 c = 'c';
443 break;
444 case AE_UNCH:
445 c = '8';
446 break;
447 case AE_FLOAT:
448 c = 'f';
449 break;
450 case AE_DOUBLE:
451 c = 'd';
452 break;
453 case AE_SHORT:
454 c = 's';
455 break;
456 case AE_LONG:
457 c = 'l';
458 break;
459 case AE_ULAW:
460 c = 'u';
461 break;
462 case AE_24INT:
463 c = '3';
464 break;
465 case AE_VORBIS:
466 c = 'v';
467 break;
468 default:
469 c = '\0';
470 };
471 while(c != sample_format_map[i].shortformat &&
472 sample_format_map[i].longformat != NULL) {
473 i++;
474 }
475 return sample_format_map[i].longformat;
476 }
477
478
479 typedef struct {
480 char *format;
481 int type;
482 } SOUNDFILE_TYPE_ENTRY;
483
484 static const SOUNDFILE_TYPE_ENTRY file_type_map[] = {
485 { "wav", TYP_WAV }, { "aiff", TYP_AIFF },
486 { "au", TYP_AU }, { "raw", TYP_RAW },
487 { "paf", TYP_PAF }, { "svx", TYP_SVX },
488 { "nist", TYP_NIST }, { "voc", TYP_VOC },
489 { "ircam", TYP_IRCAM }, { "w64", TYP_W64 },
490 { "mat4", TYP_MAT4 }, { "mat5", TYP_MAT5 },
491 { "pvf", TYP_PVF }, { "xi", TYP_XI },
492 { "htk", TYP_HTK }, { "sds", TYP_SDS },
493 { "avr", TYP_AVR }, { "wavex", TYP_WAVEX },
494 { "sd2", TYP_SD2 },
495 { "flac", TYP_FLAC }, { "caf", TYP_CAF },
496 { "wve", TYP_WVE }, { "ogg", TYP_OGG },
497 { "mpc2k", TYP_MPC2K }, { "rf64", TYP_RF64 },
498 { NULL , -1 }
499 };
500
501 extern void sfopenout(CSOUND *csound);
502 extern void sfcloseout(CSOUND *csound);
503
decode_long(CSOUND * csound,char * s,int argc,char ** argv)504 static int decode_long(CSOUND *csound, char *s, int argc, char **argv)
505 {
506 OPARMS *O = csound->oparms;
507 /* Add other long options here */
508 if (UNLIKELY(O->odebug))
509 csound->Message(csound, "decode_long %s\n", s);
510 if (!(strncmp(s, "omacro:", 7))) {
511 if (csound->orcname_mode) return 1;
512 NAMES *nn = (NAMES*) csound->Malloc(csound, sizeof(NAMES));
513 nn->mac = s;
514 nn->next = csound->omacros;
515 csound->omacros = nn;
516 return 1;
517 }
518 else if (!(strncmp(s, "smacro:", 7))) {
519 if (csound->orcname_mode) return 1;
520 NAMES *nn = (NAMES*) csound->Malloc(csound, sizeof(NAMES));
521 nn->mac = s;
522 nn->next = csound->smacros;
523 csound->smacros = nn;
524 return 1;
525 }
526 else if (!(strncmp(s, "format=", 7))) {
527 const SAMPLE_FORMAT_ENTRY *sfe;
528 const SOUNDFILE_TYPE_ENTRY *ff;
529 s += 7;
530 do {
531 char *t;
532 t = strchr(s, ':');
533 if (t != NULL)
534 *(t++) = '\0';
535 for (ff = &(file_type_map[0]); ff->format != NULL; ff++) {
536 if (strcmp(ff->format, s) == 0) {
537 O->filetyp = ff->type;
538 goto nxtToken;
539 }
540 }
541 for (sfe = &(sample_format_map[0]); sfe->longformat != NULL; sfe++) {
542 if (strcmp(s, sfe->longformat) == 0) {
543 set_output_format(O, sfe->shortformat);
544 goto nxtToken;
545 }
546 }
547 csoundErrorMsg(csound, Str("unknown output format: '%s'"), s);
548 return 0;
549 nxtToken:
550 s = t;
551 } while (s != NULL);
552 return 1;
553 }
554 /* -A */
555 else if (!(strcmp (s, "aiff"))) {
556 O->filetyp = TYP_AIFF; /* AIFF output request */
557 return 1;
558 }
559 else if (!(strcmp (s, "au"))) {
560 O->filetyp = TYP_AU; /* AU output request */
561 return 1;
562 }
563 else if (!(strncmp (s, "iobufsamps=", 11))) {
564 s += 11;
565 if (UNLIKELY(*s=='\0')) dieu(csound, Str("no iobufsamps"));
566 /* defaults in musmon.c */
567 O->inbufsamps = O->outbufsamps = atoi(s);
568 return 1;
569 }
570 else if (!(strncmp (s, "hardwarebufsamps=", 17))) {
571 s += 17;
572 if (UNLIKELY(*s=='\0')) dieu(csound, Str("no hardware bufsamps"));
573 O->inbufsamps = O->outbufsamps = atoi(s);
574 return 1;
575 }
576 else if (!(strcmp (s, "orc"))) {
577 csound->use_only_orchfile = 1; /* orchfile without scorefile */
578 return 1;
579 }
580 else if (!(strcmp (s, "cscore"))) {
581 O->usingcscore = 1; /* use cscore processing */
582 return 1;
583 }
584 else if (!(strcmp (s, "nodisplays"))) {
585 O->displays = 0; /* no func displays */
586 return 1;
587 }
588 else if (!(strcmp (s, "displays"))) {
589 O->displays = 1; /* func displays */
590 O->graphsoff = 0;
591 return 1;
592 }
593 else if (!(strcmp (s, "defer-gen1"))) {
594 O->gen01defer = 1; /* defer GEN01 sample loads */
595 return 1; /* until performance time */
596 }
597 else if (!(strncmp (s, "midifile=", 9))) {
598 s += 9;
599 if (*s==3) s++; /* skip ETX */
600 if (UNLIKELY(*s == '\0')) dieu(csound, Str("no midifile name"));
601 O->FMidiname = s; /* Midifile name */
602 if (!strcmp(O->FMidiname, "stdin")) {
603 #if defined(WIN32)
604 csoundDie(csound, Str("-F: stdin not supported on this platform"));
605 #else
606 set_stdin_assign(csound, STDINASSIGN_MIDIFILE, 1);
607 #endif
608 }
609 else
610 set_stdin_assign(csound, STDINASSIGN_MIDIFILE, 0);
611 O->FMidiin = 1; /***************/
612 return 1;
613 }
614 else if (!(strncmp (s, "midioutfile=", 12))) {
615 s += 12;
616 if (*s==3) s++; /* skip ETX */
617 if (UNLIKELY(*s == '\0')) dieu(csound, Str("no midi output file name"));
618 O->FMidioutname = s;
619 return 1;
620 }
621 /* -g */
622 else if (!(strcmp (s, "asciidisplay"))) {
623 O->graphsoff = 1; /* don't use graphics but ASCII */
624 return 1;
625 }
626 /* -G */
627 else if (!(strcmp (s, "postscriptdisplay"))) {
628 O->postscript = 1; /* don't use graphics but PostScript */
629 return 1;
630 }
631 /* -h */
632 else if (!(strcmp (s, "noheader"))) {
633 O->filetyp = TYP_RAW; /* RAW output request */
634 return 1;
635 }
636 else if (!(strncmp (s, "heartbeat=", 10))) {
637 s += 10;
638 if (*s == '\0') O->heartbeat = 1;
639 else O->heartbeat = atoi(s);
640 return 1;
641 }
642 #ifdef EMBEDDED_PYTHON
643 else if (strncmp(s, "pyvar=", 6) == 0) {
644 s += 6;
645 if (*s==3) s++; /* skip ETX */
646 if (UNLIKELY(python_add_cmdline_definition(s)))
647 dieu(csound, Str("invalid python variable definition syntax"));
648 return 1;
649 }
650 #endif
651 else if (!(strncmp (s, "input=", 6))) {
652 s += 6;
653 if (*s==3) s++; /* skip ETX */
654 if (UNLIKELY(*s == '\0')) dieu(csound, Str("no infilename"));
655 O->infilename = s; /* soundin name */
656 if (UNLIKELY(strcmp(O->infilename, "stdout") == 0))
657 csoundDie(csound, Str("input cannot be stdout"));
658 if (strcmp(O->infilename, "stdin") == 0) {
659 set_stdin_assign(csound, STDINASSIGN_SNDFILE, 1);
660 #if defined(WIN32)
661 csoundDie(csound, Str("stdin audio not supported"));
662 #endif
663 }
664 else
665 set_stdin_assign(csound, STDINASSIGN_SNDFILE, 0);
666 O->sfread = 1;
667 return 1;
668 }
669 /*
670 -I I-time only orch run
671 */
672 else if (!(strcmp (s, "i-only"))) {
673 csound->initonly = 1;
674 O->syntaxCheckOnly = 0; /* overrides --syntax-check-only */
675 O->sfwrite = 0; /* and implies nosound */
676 return 1;
677 }
678 else if (!(strcmp (s, "ircam"))) {
679 O->filetyp = TYP_IRCAM; /* IRCAM output request */
680 return 1;
681 }
682 else if (!(strcmp (s, "ogg"))) {
683 O->filetyp = TYP_OGG; /* OGG output request */
684 O->outformat = AE_VORBIS; /* Xiph Vorbis encoding */
685 return 1;
686 }
687 /*
688 -k N orchestra krate override
689 */
690 else if (!(strncmp(s, "control-rate=", 13))) {
691 s += 13;
692 if (UNLIKELY(*s=='\0')) dieu(csound, Str("no control rate"));
693 O->kr_override = (float)atof(s);
694 return 1;
695 }
696 else if (!(strncmp(s, "ksmps=", 6))) {
697 s += 6;
698 if (UNLIKELY(*s=='\0')) dieu(csound, Str("no ksmps"));
699 O->ksmps_override = atoi(s);
700 return 1;
701 }
702 /* -K */
703 else if (!(strcmp (s, "nopeaks"))) {
704 csound->peakchunks = 0; /* Do not write peak information */
705 return 1;
706 }
707 /*
708 -L dnam read Line-oriented realtime score events from device 'dnam'
709 */
710 else if (!(strncmp (s, "score-in=", 9))) {
711 s += 9;
712 if (*s==3) s++; /* skip ETX */
713 if (UNLIKELY(*s=='\0')) dieu(csound, Str("no Linein score device_name"));
714 O->Linename = s;
715 if (!strcmp(O->Linename, "stdin")) {
716 set_stdin_assign(csound, STDINASSIGN_LINEIN, 1);
717 }
718 else
719 set_stdin_assign(csound, STDINASSIGN_LINEIN, 0);
720 O->Linein = 1;
721 return 1;
722 }
723 /*
724 -m N tty message level.
725 Sum of: 1=note amps, 2=out-of-range msg, 4=warnings
726 */
727 else if (!(strncmp (s, "messagelevel=", 13))) {
728 s += 13;
729 if (UNLIKELY(*s=='\0')) dieu(csound, Str("no message level"));
730 O->msglevel = atoi(s);
731 return 1;
732 }
733 else if (!(strncmp (s, "messageolevel=", 14))) {
734 s += 14;
735 if (UNLIKELY(*s=='\0')) dieu(csound, Str("no message level"));
736 sscanf(s, "%o", &(O->msglevel));
737 return 1;
738 }
739 else if (!(strncmp (s, "m-amps=", 7))) {
740 int n;
741 s += 7;
742 if (UNLIKELY(*s=='\0')) dieu(csound, Str("no message amps"));
743 sscanf(s, "%d", &n);
744 if (n) O->msglevel |= AMPLMSG;
745 else O->msglevel &= ~AMPLMSG;
746 return 1;
747 }
748 else if (!(strncmp (s, "m-range=",8))) {
749 int n;
750 s += 8;
751 if (UNLIKELY(*s=='\0')) dieu(csound, Str("no message range"));
752 sscanf(s, "%d", &n);
753 if (n) O->msglevel |= RNGEMSG;
754 else O->msglevel &= ~RNGEMSG;
755 return 1;
756 }
757 else if (!(strncmp (s, "m-warnings=",11))) {
758 int n;
759 s += 11;
760 if (UNLIKELY(*s=='\0')) dieu(csound, Str("no message warnings"));
761 sscanf(s, "%d", &n);
762 if (n) O->msglevel |= WARNMSG;
763 else O->msglevel &= ~WARNMSG;
764 return 1;
765 }
766 else if (!(strncmp (s, "m-raw=",6))) {
767 int n;
768 s += 6;
769 if (UNLIKELY(*s=='\0')) dieu(csound, Str("no message raw"));
770 sscanf(s, "%d", &n);
771 if (n) O->msglevel |= 32;
772 else O->msglevel &= ~32;
773 return 1;
774 }
775 else if (!(strncmp (s, "m-dB=",5))) {
776 int n;
777 s += 5;
778 if (UNLIKELY(*s=='\0')) dieu(csound, Str("no message dB"));
779 sscanf(s, "%d", &n);
780 if (n) O->msglevel |= RAWMSG;
781 else O->msglevel &= ~RAWMSG;
782 return 1;
783 }
784 else if (!(strncmp (s, "m-colours=",10)) || !(strncmp (s, "m-colors=",9))) {
785 int n;
786 s += 10;
787 if (*s=='\0') dieu(csound, Str("no message colours"));
788 sscanf(s, "%d", &n);
789 if (n) O->msglevel |= 96;
790 else O->msglevel &= ~96;
791 return 1;
792 }
793 else if (!(strncmp (s, "m-benchmarks=",13))) {
794 int n;
795 s += 13;
796 if (UNLIKELY(*s=='\0')) dieu(csound, Str("no benchmark level"));
797 sscanf(s, "%d", &n);
798 if (n) O->msglevel |= TIMEMSG;
799 else O->msglevel &= ~TIMEMSG;
800 return 1;
801 }
802 else if (!(strncmp (s, "csd-line-nums=",14))) {
803 s += 14;
804 if (UNLIKELY(*s=='\0')) dieu(csound, Str("no value for --csd-line-nums"));
805 O->useCsdLineCounts = (atoi(s) != 0);
806 return 1;
807 }
808 /*
809 -M dnam read MIDI realtime events from device 'dnam'
810 */
811 else if (!(strncmp (s, "midi-device=", 12))) {
812 s += 12;
813 if (*s==3) s++; /* skip ETX */
814 if (UNLIKELY(*s=='\0')) dieu(csound, Str("no midi device_name"));
815 O->Midiname = s;
816 if (!strcmp(O->Midiname, "stdin")) {
817 set_stdin_assign(csound, STDINASSIGN_MIDIDEV, 1);
818 #if defined(WIN32)
819 csoundDie(csound, Str("-M: stdin not supported on this platform"));
820 #endif
821 }
822 else
823 set_stdin_assign(csound, STDINASSIGN_MIDIDEV, 0);
824 O->Midiin = 1;
825 return 1;
826 }
827 /* -n no sound */
828 else if (!(strcmp (s, "nosound"))) {
829 O->sfwrite = 0; /* nosound */
830 return 1;
831 }
832 /* -N */
833 else if (!(strcmp (s, "notify"))) {
834 O->ringbell = 1; /* notify on completion */
835 return 1;
836 }
837 else if (!(strncmp (s, "output=", 7))) {
838 s += 7;
839 if (*s==3) s++; /* skip ETX */
840 if (UNLIKELY(*s == '\0')) dieu(csound, Str("no outfilename"));
841 O->outfilename = s; /* soundout name */
842 if (UNLIKELY(strcmp(O->outfilename, "stdin")) == 0)
843 dieu(csound, Str("-o cannot be stdin"));
844 if (strcmp(O->outfilename, "stdout") == 0) {
845 set_stdout_assign(csound, STDOUTASSIGN_SNDFILE, 1);
846 #if defined(WIN32)
847 csoundDie(csound, Str("stdout audio not supported"));
848 #endif
849 }
850 else
851 set_stdout_assign(csound, STDOUTASSIGN_SNDFILE, 0);
852 O->sfwrite = 1;
853 return 1;
854 }
855 else if (!(strcmp (s, "print_version"))) {
856 csound->print_version = 1;
857 return 1;
858 }
859 else if (!(strncmp (s, "logfile=", 8))) {
860 s += 8;
861 if (UNLIKELY(*s=='\0')) dieu(csound, Str("no log file"));
862 do_logging(s);
863 return 1;
864 }
865 /* -r N */
866 else if (!(strncmp (s, "sample-rate=", 12))) {
867 s += 12;
868 if (*s==3) s++; /* skip ETX */
869 O->sr_override = (float)atof(s);
870 return 1;
871 }
872 /* R */
873 else if (!(strcmp (s, "rewrite"))) {
874 O->rewrt_hdr = 1;
875 return 1;
876 }
877 /* -S */
878 /* tempo=N use uninterpreted beats of the score, initially at tempo N
879 */
880 else if (UNLIKELY(!(strncmp (s, "tempo=", 6)))) {
881 s += 6;
882 O->cmdTempo = atof(s);
883 O->Beatmode = 1; /* on uninterpreted Beats */
884 return 1;
885 }
886 /* -t0 */
887 else if (!(strncmp(s, "keep-sorted-score=", 18))) {
888 s += 18;
889 csound->score_srt = s;
890 csound->keep_tmp= 1;
891 return 1;
892 }
893 else if (!(strcmp (s, "keep-sorted-score"))) {
894 csound->keep_tmp= 1;
895 return 1;
896 }
897 else if (!(strncmp (s, "simple-sorted-score=", 20))) {
898 s +=20;
899 csound->score_srt = s;
900 csound->keep_tmp = 2;
901 return 1;
902 }
903 else if (!(strcmp (s, "simple-sorted-score"))) {
904 csound->keep_tmp = 2;
905 return 1;
906 }
907 /* IV - Jan 27 2005: --expression-opt */
908 /* NOTE these do nothing */
909 else if (!(strcmp (s, "expression-opt"))) {
910 //O->expr_opt = 1;
911 csound->Warning(csound, Str("option expresson-opt has no affect\n"));
912 return 1;
913 }
914 else if (!(strcmp (s, "no-expression-opt"))) {
915 //O->expr_opt = 0;
916 csound->Warning(csound, Str("option no-expresson-opt has no affect\n"));
917 return 1;
918 }
919 else if (!(strncmp (s, "env:", 4))) {
920 if (csoundParseEnv(csound, s + 4) == CSOUND_SUCCESS)
921 return 1;
922 else
923 return 0;
924 }
925 else if (!(strncmp (s, "strset", 6))) {
926 strset_option(csound, s + 6);
927 return 1;
928 }
929 /* -T terminate the performance when miditrack is done */
930 else if (!(strcmp (s, "terminate-on-midi"))) {
931 O->termifend = 1; /* terminate on midifile end */
932 return 1;
933 }
934 else if (!(strncmp (s, "utility=", 8))) {
935 int retval;
936 s += 8;
937 if (*s==3) s++; /* skip ETX */
938 if (*s=='\0') dieu(csound, Str("no utility name"));
939
940 retval = csoundRunUtility(csound, s, argc, argv);
941 if (retval) {
942 csound->info_message_request = 1;
943 csound->orchname = NULL;
944 return 0;
945 }
946 else csound->LongJmp(csound, retval);
947 return 1;
948 }
949 /* -v */
950 else if (!(strcmp (s, "verbose"))) {
951 O->odebug = 1; /* verbose otran */
952 return 1;
953 }
954 /* -x fnam extract from score.srt using extract file 'fnam' */
955 else if (!(strncmp(s, "extract-score=", 14))) {
956 s += 14;
957 if (UNLIKELY(*s=='\0')) dieu(csound, Str("no xfilename"));
958 csound->xfilename = s;
959 return 1;
960 }
961 else if (!(strcmp(s, "wave"))) {
962 O->filetyp = TYP_WAV; /* WAV output request */
963 return 1;
964 }
965 else if (!(strncmp (s, "list-opcodes", 12))) {
966 int full = 0;
967 s += 12;
968
969 if (*s != '\0') {
970 if (isdigit(*s)) full = *s++ - '0';
971 }
972 list_opcodes(csound, full);
973 return 1;
974 //csound->LongJmp(csound, 0);
975 }
976 /* -Z */
977 else if (!(strcmp (s, "dither"))) {
978 csound->dither_output = 1;
979 return 1;
980 }
981 else if (!(strcmp (s, "dither-uniform"))) {
982 csound->dither_output = 2;
983 return 1;
984 }
985 else if (!(strcmp (s, "dither-triangular"))) {
986 csound->dither_output = 1;
987 return 1;
988 }
989 else if (!(strncmp (s, "midi-key=", 9))) {
990 s += 9;
991 O->midiKey = atoi(s);
992 return 1;
993 }
994 else if (!(strncmp (s, "midi-key-cps=", 13))) {
995 s += 13 ;
996 O->midiKeyCps = atoi(s);
997 return 1;
998 }
999 else if (!(strncmp (s, "midi-key-oct=", 13))) {
1000 s += 13 ;
1001 O->midiKeyOct = atoi(s);
1002 return 1;
1003 }
1004 else if (!(strncmp (s, "midi-key-pch=", 13))) {
1005 s += 13 ;
1006 O->midiKeyPch = atoi(s);
1007 return 1;
1008 }
1009 else if (!(strncmp (s, "midi-velocity=", 14))) {
1010 s += 14;
1011 O->midiVelocity = atoi(s);
1012 return 1;
1013 }
1014 else if (!(strncmp (s, "midi-velocity-amp=", 18))) {
1015 s += 18;
1016 O->midiVelocityAmp = atoi(s);
1017 return 1;
1018 }
1019 else if (!(strncmp (s, "opcode-dir=", 11))){
1020 s += 11;
1021 csoundLoadPlugins(csound, s);
1022 return 1;
1023 }
1024 else if (!(strncmp (s, "opcode-lib=", 11))) {
1025 int nbytes;
1026 s += 11;
1027 if (*s==3) s++; /* skip ETX */
1028 nbytes = (int) strlen(s) + 1;
1029 if (csound->dl_opcodes_oplibs == NULL) {
1030 /* start new library list */
1031 csound->dl_opcodes_oplibs = (char*) csound->Malloc(csound, (size_t) nbytes);
1032 strcpy(csound->dl_opcodes_oplibs, s);
1033 }
1034 else {
1035 /* append to existing list */
1036 nbytes += ((int) strlen(csound->dl_opcodes_oplibs) + 1);
1037 csound->dl_opcodes_oplibs = (char*) csound->ReAlloc(csound,
1038 csound->dl_opcodes_oplibs,
1039 (size_t) nbytes);
1040 strcat(csound->dl_opcodes_oplibs, ",");
1041 strcat(csound->dl_opcodes_oplibs, s);
1042 }
1043 return 1;
1044 }
1045 else if (!(strcmp(s, "default-paths"))) {
1046 O->noDefaultPaths = 0;
1047 return 1;
1048 }
1049 else if (!(strcmp(s, "no-default-paths"))) {
1050 O->noDefaultPaths = 1;
1051 return 1;
1052 }
1053 else if (!(strncmp (s, "num-threads=", 12))) {
1054 s += 12 ;
1055 O->numThreads = atoi(s);
1056 return 1;
1057 }
1058 else if (!(strcmp (s, "syntax-check-only"))) {
1059 O->syntaxCheckOnly = 1;
1060 return 1;
1061 }
1062 else if (!(strcmp(s, "version"))) {
1063 //print_csound_version(csound); // as already printed!
1064 csound->LongJmp(csound, 0);
1065 }
1066 else if (!(strcmp(s, "help"))) {
1067 longusage(csound);
1068 csound->info_message_request = 1;
1069 return 1;
1070 //csound->LongJmp(csound, 0);
1071 }
1072 else if (!(strcmp(s, "sample-accurate"))) {
1073 O->sampleAccurate = 1;
1074 return 1;
1075 }
1076 else if (!(strcmp(s, "realtime"))) {
1077 csound->Message(csound, Str("realtime mode enabled\n"));
1078 O->realtime = 1;
1079 return 1;
1080 }
1081 else if (!(strncmp(s, "nchnls=", 7))) {
1082 s += 7;
1083 O->nchnls_override = atoi(s);
1084 return 1;
1085 }
1086 else if (!(strncmp(s, "0dbfs=", 6))) {
1087 s += 6;
1088 O->e0dbfs_override = atoi(s);
1089 return 1;
1090 }
1091 else if (!(strncmp(s, "nchnls_i=", 9))) {
1092 s += 9;
1093 O->nchnls_i_override = atoi(s);
1094 return 1;
1095 }
1096 else if (!(strncmp(s, "sinesize=", 9))) {
1097 {
1098 int i = 1, n;
1099 s += 9;
1100 n = atoi(s);
1101 while (i<=n && i< MAXLEN) i <<= 1;
1102 csound->sinelength = i;
1103 return 1;
1104 }
1105 }
1106 else if (!(strcmp(s, "new-parser")) ||
1107 !(strcmp(s, "old-parser"))) {
1108 return 1; /* ignore flag, this is here for backwards compatibility */
1109 }
1110 else if (!(strcmp(s, "sco-parser"))) {
1111 csound->score_parser = 1;
1112 return 1; /* Try new parser */
1113 }
1114 else if (!(strcmp(s, "daemon"))) {
1115 if(O->daemon == 0) O->daemon = 1;
1116 return 1;
1117 }
1118 else if (!(strncmp(s, "port=",5))) {
1119 s += 5;
1120 O->daemon = atoi(s);
1121 return 1;
1122 }
1123 else if (!(strncmp(s, "udp-echo",8))) {
1124 s += 8;
1125 O->echo = 1;
1126 return 1;
1127 }
1128 else if (!(strncmp(s, "udp-console=",12))) {
1129 char *ports;
1130 s += 12;
1131 ports = strchr(s, ':');
1132 if(*s != '\0' && ports != NULL) {
1133 *ports = '\0';
1134 csoundUDPConsole(csound, s, atoi(ports+1),0);
1135 } else
1136 csound->Warning(csound, "UDP console: needs address and port\n");
1137 return 1;
1138 }
1139 else if (!(strncmp(s, "udp-mirror-console=",19))) {
1140 char *ports;
1141 s += 19;
1142 ports = strchr(s, ':');
1143 if(*s != '\0' && ports != NULL) {
1144 *ports = '\0';
1145 csoundUDPConsole(csound, s, atoi(ports+1),1);
1146 } else
1147 csound->Warning(csound, "UDP console: needs address and port\n");
1148 return 1;
1149 }
1150 else if (!(strncmp(s, "fftlib=",7))) {
1151 s += 7;
1152 O->fft_lib = atoi(s);
1153 return 1;
1154 }
1155 else if (!(strncmp(s, "vbr-quality=",12))) {
1156 s += 12;
1157 O->quality = atof(s);
1158 return 1;
1159 }
1160 else if (!(strncmp(s, "devices",7))) {
1161 csoundLoadExternals(csound);
1162 if (csoundInitModules(csound) != 0)
1163 csound->LongJmp(csound, 1);
1164 if (*(s+7) == '='){
1165 if (!strncmp(s+8,"in", 2)) {
1166 list_audio_devices(csound, 0);
1167 }
1168 else if (!strncmp(s+8,"out", 2))
1169 list_audio_devices(csound,1);
1170 }
1171 else {
1172 list_audio_devices(csound,0);
1173 list_audio_devices(csound,1);
1174 }
1175 csound->info_message_request = 1;
1176 return 1;
1177 }
1178 else if (!(strncmp(s, "midi-devices",12))) {
1179 csoundLoadExternals(csound);
1180 if (csoundInitModules(csound) != 0)
1181 csound->LongJmp(csound, 1);
1182 if (*(s+12) == '='){
1183 if (!strncmp(s+13,"in", 2)) {
1184 list_midi_devices(csound, 0);
1185 }
1186 else if (!strncmp(s+13,"out", 2))
1187 list_midi_devices(csound,1);
1188 }
1189 else {
1190 list_midi_devices(csound,0);
1191 list_midi_devices(csound,1);
1192 }
1193 csound->info_message_request = 1;
1194 return 1;
1195 }
1196 else if (!(strncmp(s, "get-system-sr",13)) ){
1197 if (O->outfilename &&
1198 !(strncmp(O->outfilename, "dac",3))) {
1199 /* these are default values to get the
1200 backend to open successfully */
1201 set_output_format(O, 'f');
1202 O->inbufsamps = O->outbufsamps = 256;
1203 O->oMaxLag = 1024;
1204 csoundLoadExternals(csound);
1205 if (csoundInitModules(csound) != 0)
1206 csound->LongJmp(csound, 1);
1207 sfopenout(csound);
1208 csound->MessageS(csound,CSOUNDMSG_STDOUT,
1209 "system sr: %f\n", csound->system_sr(csound,0));
1210 sfcloseout(csound);
1211 }
1212 csound->info_message_request = 1;
1213 return 1;
1214 }
1215 else if(!strncmp(s, "use-system-sr",13)){
1216 if (O->sr_override == FL(0.0))
1217 O->sr_override = FL(-1.0);
1218 return 1;
1219 }
1220 else if (!(strcmp(s, "aft-zero"))){
1221 csound->aftouch = 0;
1222 return 1;
1223 }
1224
1225 csoundErrorMsg(csound, Str("unknown long option: '--%s'"), s);
1226 return 0;
1227 }
1228
argdecode(CSOUND * csound,int argc,const char ** argv_)1229 PUBLIC int argdecode(CSOUND *csound, int argc, const char **argv_)
1230 {
1231 OPARMS *O = csound->oparms;
1232 char *s, **argv;
1233 int n;
1234 char c;
1235
1236 /* make a copy of the option list */
1237 char *p1, *p2;
1238 int nbytes, i;
1239 /* calculate the number of bytes to allocate */
1240 /* N.B. the argc value passed to argdecode is decremented by one */
1241 nbytes = (argc + 1) * (int) sizeof(char*);
1242 for (i = 0; i <= argc; i++)
1243 nbytes += ((int) strlen(argv_[i]) + 1);
1244 p1 = (char*) csound->Malloc(csound, nbytes); /* will be freed by memRESET() */
1245 p2 = (char*) p1 + ((int) sizeof(char*) * (argc + 1));
1246 argv = (char**) p1;
1247 for (i = 0; i <= argc; i++) {
1248 argv[i] = p2;
1249 strcpy(p2, argv_[i]);
1250 p2 = (char*) p2 + ((int) strlen(argv_[i]) + 1);
1251 }
1252 //<csound->keep_tmp = 0;
1253
1254 do {
1255 s = *++argv;
1256 if (*s++ == '-') { /* read all flags: */
1257 while ((c = *s++) != '\0') {
1258 switch (c) {
1259 case 'U':
1260 FIND(Str("no utility name"));
1261 {
1262 int retval = csoundRunUtility(csound, s, argc, argv);
1263 if (retval) {
1264 csound->info_message_request = 1;
1265 csound->orchname = NULL;
1266 goto end;
1267 }
1268 else csound->LongJmp(csound, retval);
1269 }
1270 break;
1271 case 'C':
1272 O->usingcscore = 1; /* use cscore processing */
1273 break;
1274 case 'I':
1275 csound->initonly = 1; /* I-only overrides */
1276 O->syntaxCheckOnly = 0; /* --syntax-check-only and implies */
1277 /* FALLTHRU */
1278 case 'n':
1279 O->sfwrite = 0; /* nosound */
1280 break;
1281 case 'i':
1282 FIND(Str("no infilename"));
1283 O->infilename = s; /* soundin name */
1284 s += (int) strlen(s);
1285 if (UNLIKELY(strcmp(O->infilename, "stdout")) == 0)
1286 csoundDie(csound, Str("input cannot be stdout"));
1287 if (strcmp(O->infilename, "stdin") == 0) {
1288 set_stdin_assign(csound, STDINASSIGN_SNDFILE, 1);
1289 #if defined(WIN32)
1290 csoundDie(csound, Str("stdin audio not supported"));
1291 #endif
1292 }
1293 else
1294 set_stdin_assign(csound, STDINASSIGN_SNDFILE, 0);
1295 O->sfread = 1;
1296 break;
1297 case 'o':
1298 FIND(Str("no outfilename"));
1299 O->outfilename = s; /* soundout name */
1300 s += (int) strlen(s);
1301 if (UNLIKELY(strcmp(O->outfilename, "stdin") == 0))
1302 dieu(csound, Str("-o cannot be stdin"));
1303 if (strcmp(O->outfilename, "stdout") == 0) {
1304 set_stdout_assign(csound, STDOUTASSIGN_SNDFILE, 1);
1305 #if defined(WIN32)
1306 csoundDie(csound, Str("stdout audio not supported"));
1307 #endif
1308 }
1309 else
1310 set_stdout_assign(csound, STDOUTASSIGN_SNDFILE, 0);
1311 O->sfwrite = 1;
1312 break;
1313 case 'b':
1314 FIND(Str("no iobufsamps"));
1315 sscanf(s, "%d%n", &(O->outbufsamps), &n);
1316 /* defaults in musmon.c */
1317 O->inbufsamps = O->outbufsamps;
1318 s += n;
1319 break;
1320 case 'B':
1321 FIND(Str("no hardware bufsamps"));
1322 sscanf(s, "%d%n", &(O->oMaxLag), &n);
1323 /* defaults in rtaudio.c */
1324 s += n;
1325 break;
1326 case 'A':
1327 O->filetyp = TYP_AIFF; /* AIFF output request*/
1328 break;
1329 case 'J':
1330 O->filetyp = TYP_IRCAM; /* IRCAM output request */
1331 break;
1332 case 'W':
1333 O->filetyp = TYP_WAV; /* WAV output request */
1334 break;
1335 case 'h':
1336 O->filetyp = TYP_RAW; /* RAW output request */
1337 break;
1338 case 'c':
1339 case 'a':
1340 case 'u':
1341 case '8':
1342 case 's':
1343 case '3':
1344 case 'l':
1345 case 'f':
1346 set_output_format(O, c);
1347 break;
1348 case 'r':
1349 FIND(Str("no sample rate"));
1350 O->sr_override = (float)atof(s);
1351 while (*++s);
1352 break;
1353 case 'k':
1354 FIND(Str("no control rate"));
1355 O->kr_override = (float)atof(s);
1356 while (*++s);
1357 break;
1358 case 'v':
1359 O->odebug = 1; /* verbose otran */
1360 break;
1361 case 'm':
1362 FIND(Str("no message level"));
1363 sscanf(s, "%d%n", &(O->msglevel), &n);
1364 s += n;
1365 break;
1366 case 'd':
1367 O->displays = 0; /* no func displays */
1368 break;
1369 case 'g':
1370 O->graphsoff = 1; /* don't use graphics */
1371 break;
1372 case 'G':
1373 O->postscript = 1; /* Postscript graphics*/
1374 break;
1375 case 'x':
1376 FIND(Str("no xfilename"));
1377 csound->xfilename = s; /* extractfile name */
1378 while (*++s);
1379 break;
1380 case 't':
1381 FIND(Str("no tempo value"));
1382 {
1383 double val;
1384 sscanf(s, "%lg%n", &val, &n); /* use this tempo .. */
1385 s += n;
1386 if (UNLIKELY(val < 0.0)) dieu(csound, Str("illegal tempo"));
1387 else if (val == 0.0) {
1388 csound->keep_tmp = 1;
1389 break;
1390 }
1391 O->cmdTempo = val;
1392 O->Beatmode = 1; /* on uninterpreted Beats */
1393 }
1394 break;
1395 case 'L':
1396 FIND(Str("no Linein score device_name"));
1397 O->Linename = s; /* Linein device name */
1398 s += (int) strlen(s);
1399 if (!strcmp(O->Linename, "stdin")) {
1400 set_stdin_assign(csound, STDINASSIGN_LINEIN, 1);
1401 }
1402 else
1403 set_stdin_assign(csound, STDINASSIGN_LINEIN, 0);
1404 O->Linein = 1;
1405 break;
1406 case 'M':
1407 FIND(Str("no midi device_name"));
1408 O->Midiname = s; /* Midi device name */
1409 s += (int) strlen(s);
1410 if (strcmp(O->Midiname, "stdin")==0) {
1411 #if defined(WIN32)
1412 csoundDie(csound, Str("-M: stdin not supported on this platform"));
1413 #else
1414 set_stdin_assign(csound, STDINASSIGN_MIDIDEV, 1);
1415 #endif
1416 }
1417 else
1418 set_stdin_assign(csound, STDINASSIGN_MIDIDEV, 0);
1419 O->Midiin = 1;
1420 break;
1421 case 'F':
1422 FIND(Str("no midifile name"));
1423 O->FMidiname = s; /* Midifile name */
1424 s += (int) strlen(s);
1425 if (strcmp(O->FMidiname, "stdin")==0) {
1426 #if defined(WIN32)
1427 csoundDie(csound, Str("-F: stdin not supported on this platform"));
1428 #else
1429 set_stdin_assign(csound, STDINASSIGN_MIDIFILE, 1);
1430 #endif
1431 }
1432 else
1433 set_stdin_assign(csound, STDINASSIGN_MIDIFILE, 0);
1434 O->FMidiin = 1; /*****************/
1435 break;
1436 case 'Q':
1437 FIND(Str("no MIDI output device"));
1438 O->Midioutname = s;
1439 s += (int) strlen(s);
1440 break;
1441 case 'R':
1442 O->rewrt_hdr = 1;
1443 break;
1444 case 'H':
1445 if (isdigit(*s)) {
1446 sscanf(s, "%d%n", &(O->heartbeat), &n);
1447 s += n;
1448 }
1449 else O->heartbeat = 1;
1450 break;
1451 case 'N':
1452 O->ringbell = 1; /* notify on completion */
1453 break;
1454 case 'T':
1455 O->termifend = 1; /* terminate on midifile end */
1456 break;
1457 case 'D':
1458 O->gen01defer = 1; /* defer GEN01 sample loads
1459 until performance time */
1460 break;
1461 case 'K':
1462 csound->peakchunks = 0; /* Do not write peak information */
1463 break;
1464 case 'z':
1465 {
1466 int full = 0;
1467 if (*s != '\0') {
1468 if (isdigit(*s)) full = *s++ - '0';
1469 }
1470 list_opcodes(csound, full);
1471 }
1472 csound->info_message_request = 1;
1473 // csound->LongJmp(csound, 0);
1474 break;
1475 case 'Z':
1476 {
1477 int full = 1;
1478 if (*s != '\0') {
1479 if (isdigit(*s)) full = *s++ - '0';
1480 }
1481 csound->dither_output = full;
1482 }
1483 break;
1484 case '@':
1485 FIND(Str("No indirection file"));
1486 {
1487 FILE *ind;
1488 void *fd;
1489 fd = csound->FileOpen2(csound, &ind, CSFILE_STD,
1490 s, "r", NULL, CSFTYPE_OPTIONS, 0);
1491 if (UNLIKELY(fd == NULL)) {
1492 dieu(csound, Str("Cannot open indirection file %s\n"), s);
1493 }
1494 else {
1495 CORFIL *cf = copy_to_corefile(csound, s, NULL, 0);
1496 readOptions(csound, cf, 0);
1497 corfile_rm(csound, &cf);
1498 csound->FileClose(csound, fd);
1499 }
1500 while (*s++) {};
1501 s--; /* semicolon on separate line to silence warning */
1502 }
1503 break;
1504 case 'O':
1505 FIND(Str("no log file"));
1506 do_logging(s);
1507 while (*s++) {};
1508 s--; /* semicolon on separate line to silence warning */
1509 break;
1510 case '-':
1511 #if defined(LINUX)
1512 if (!(strcmp (s, "sched"))) { /* ignore --sched */
1513 while (*(++s));
1514 break;
1515 }
1516 if (!(strncmp(s, "sched=", 6))) {
1517 while (*(++s));
1518 break;
1519 }
1520 #endif
1521 if (!decode_long(csound, s, argc, argv))
1522 csound->LongJmp(csound, 1);
1523 while (*(++s));
1524 break;
1525 case 'j':
1526 FIND(Str("no number of threads"));
1527 sscanf(s, "%d%n", &(O->numThreads), &n);
1528 s += n;
1529 break;
1530 case '+': /* IV - Feb 01 2005 */
1531 if (parse_option_as_cfgvar(csound, (char*) s - 2) != 0)
1532 csound->LongJmp(csound, 1);
1533 while (*(++s));
1534 break;
1535 default:
1536 if (csound->info_message_request == 0)
1537 dieu(csound, Str("unknown flag -%c"), c);
1538 }
1539 }
1540 }
1541 else {
1542 /* 0: normal, 1: ignore, 2: fail */
1543 if (csound->orcname_mode == 2) {
1544 csound->Die(csound, Str("error: orchestra and score name not "
1545 "allowed in .csound6rc"));
1546 }
1547 else if (csound->orcname_mode == 0) {
1548 if (csound->orchname == NULL) /* VL dec 2016: better duplicate these */
1549 csound->orchname = cs_strdup(csound, --s);
1550 else if (LIKELY(csound->scorename == NULL))
1551 csound->scorename = cs_strdup(csound, --s);
1552 else {
1553 csound->Message(csound,"argc=%d Additional string \"%s\"\n",argc,--s);
1554 dieu(csound, Str("too many arguments"));
1555 }
1556 }
1557 }
1558 } while (--argc);
1559 end:
1560 return 1;
1561 }
1562
csoundSetOption(CSOUND * csound,const char * option)1563 PUBLIC int csoundSetOption(CSOUND *csound, const char *option){
1564 /* if already compiled and running, return */
1565 if (csound->engineStatus & CS_STATE_COMP) return 1;
1566 else {
1567 const char *args[2] = {"csound", option};
1568 csound->info_message_request = 1;
1569 return (argdecode(csound, 1, args) ? 0 : 1);
1570 }
1571 }
1572
csoundSetParams(CSOUND * csound,CSOUND_PARAMS * p)1573 PUBLIC void csoundSetParams(CSOUND *csound, CSOUND_PARAMS *p){
1574 OPARMS *oparms = csound->oparms;
1575 /* if already compiled and running, return */
1576 if (csound->engineStatus & CS_STATE_COMP) return;
1577
1578 /* simple ON/OFF switches */
1579 oparms->odebug = p->debug_mode;
1580 oparms->displays = p->displays;
1581 oparms->graphsoff = p->ascii_graphs;
1582 oparms->postscript = p->postscript_graphs;
1583 oparms->usingcscore = p->use_cscore;
1584 oparms->ringbell = p->ring_bell;
1585 oparms->gen01defer = p->defer_gen01_load;
1586 oparms->termifend = p->terminate_on_midi;
1587 oparms->noDefaultPaths = p->no_default_paths;
1588 oparms->syntaxCheckOnly = p->syntax_check_only;
1589 oparms->sampleAccurate = p->sample_accurate;
1590 oparms->realtime = p->realtime_mode;
1591 oparms->useCsdLineCounts = p->csd_line_counts;
1592 oparms->heartbeat = p->heartbeat;
1593 oparms->ringbell = p->ring_bell;
1594 oparms->daemon = p->daemon;
1595
1596 /* message level */
1597 if (p->message_level > 0)
1598 oparms->msglevel = p->message_level;
1599
1600 /* tempo / beatmode */
1601 if (p->tempo > 0) {
1602 oparms->cmdTempo = p->tempo;
1603 oparms->Beatmode = 1;
1604 }
1605 /* buffer frames */
1606 if (p->buffer_frames > 0)
1607 oparms->inbufsamps = oparms->outbufsamps = p->buffer_frames;
1608
1609 /* hardware buffer frames */
1610 if (p->hardware_buffer_frames > 0)
1611 oparms->oMaxLag = p->hardware_buffer_frames;
1612
1613 /* multicore threads */
1614 if (p->number_of_threads > 1)
1615 oparms->numThreads = p->number_of_threads;
1616
1617 /* MIDI interop */
1618 if (p->midi_key > 0) oparms->midiKey = p->midi_key;
1619 else if (p->midi_key_cps > 0) oparms->midiKeyCps = p->midi_key_cps;
1620 else if (p->midi_key_pch > 0) oparms->midiKeyPch = p->midi_key_pch;
1621 else if (p->midi_key_oct > 0) oparms->midiKeyOct = p->midi_key_oct;
1622
1623 if (p->midi_velocity > 0) oparms->midiVelocity = p->midi_velocity;
1624 else if (p->midi_velocity_amp > 0)
1625 oparms->midiVelocityAmp = p->midi_velocity_amp;
1626
1627 /* CSD line counts */
1628 if (p->csd_line_counts > 0) oparms->useCsdLineCounts = p->csd_line_counts;
1629
1630 /* kr override */
1631 if (p->control_rate_override > 0)
1632 oparms->kr_override = p->control_rate_override;
1633
1634 /* sr override */
1635 if (p->sample_rate_override > 0)
1636 oparms->sr_override = p->sample_rate_override;
1637
1638 oparms->nchnls_override = p->nchnls_override;
1639 oparms->nchnls_i_override = p->nchnls_i_override;
1640 oparms->e0dbfs_override = p->e0dbfs_override;
1641
1642 if (p->ksmps_override > 0) oparms->ksmps_override = p->ksmps_override;
1643 }
1644
csoundGetParams(CSOUND * csound,CSOUND_PARAMS * p)1645 PUBLIC void csoundGetParams(CSOUND *csound, CSOUND_PARAMS *p){
1646
1647 OPARMS *oparms = csound->oparms;
1648
1649 p->debug_mode = oparms->odebug;
1650 p->displays = oparms->displays;
1651 p->ascii_graphs = oparms->graphsoff;
1652 p->postscript_graphs = oparms->postscript;
1653 p->use_cscore = oparms->usingcscore;
1654 p->ring_bell = oparms->ringbell;
1655 p->defer_gen01_load = oparms->gen01defer;
1656 p->terminate_on_midi = oparms->termifend;
1657 p->no_default_paths = oparms->noDefaultPaths;
1658 p->syntax_check_only = oparms->syntaxCheckOnly;
1659 p->sample_accurate = oparms->sampleAccurate;
1660 p->realtime_mode = oparms->realtime;
1661 p->message_level = oparms->msglevel;
1662 p->tempo = oparms->cmdTempo;
1663 p->buffer_frames = oparms->outbufsamps;
1664 p->hardware_buffer_frames = oparms->oMaxLag;
1665 p->number_of_threads = oparms->numThreads;
1666 p->midi_key = oparms->midiKey;
1667 p->midi_key_cps = oparms->midiKeyCps;
1668 p->midi_key_pch = oparms->midiKeyPch;
1669 p->midi_key_oct = oparms->midiKeyOct;
1670 p->midi_velocity = oparms->midiVelocity;
1671 p->midi_velocity_amp = oparms->midiVelocityAmp;
1672 p->csd_line_counts = oparms->useCsdLineCounts;
1673 p->control_rate_override = oparms->kr_override;
1674 p->sample_rate_override = oparms->sr_override;
1675 p->nchnls_override = oparms->nchnls_override;
1676 p->nchnls_i_override = oparms->nchnls_i_override;
1677 p->e0dbfs_override = oparms->e0dbfs_override;
1678 p->heartbeat = oparms->heartbeat;
1679 p->ring_bell = oparms->ringbell;
1680 p->daemon = oparms->daemon;
1681 p->ksmps_override = oparms->ksmps_override;
1682 p->FFT_library = oparms->fft_lib;
1683 }
1684
1685
csoundSetOutput(CSOUND * csound,const char * name,const char * type,const char * format)1686 PUBLIC void csoundSetOutput(CSOUND *csound, const char *name,
1687 const char *type, const char *format)
1688 {
1689
1690 OPARMS *oparms = csound->oparms;
1691 char *typename;
1692
1693 /* if already compiled and running, return */
1694 if (csound->engineStatus & CS_STATE_COMP) return;
1695
1696 oparms->outfilename =
1697 csound->Malloc(csound, strlen(name) + 1); /* will be freed by memRESET */
1698 strcpy(oparms->outfilename, name); /* unsafe -- REVIEW */
1699 if (strcmp(oparms->outfilename, "stdout") == 0) {
1700 set_stdout_assign(csound, STDOUTASSIGN_SNDFILE, 1);
1701 #if defined(WIN32)
1702 csound->Warning(csound, Str("stdout not supported on this platform"));
1703 #endif
1704 }
1705 else set_stdout_assign(csound, STDOUTASSIGN_SNDFILE, 0);
1706
1707 oparms->sfwrite = 1;
1708 if (type != NULL) {
1709 int i=0;
1710 while ((typename = file_type_map[i].format) != NULL) {
1711 if (!strcmp(type,typename)) break;
1712 i++;
1713 }
1714 if (typename != NULL) {
1715 oparms->filetyp = file_type_map[i].type;
1716 }
1717 }
1718 if (format != NULL) {
1719 int i=0;
1720 while ((typename = sample_format_map[i].longformat) != NULL) {
1721 if (!strcmp(format,typename)) break;
1722 i++;
1723 }
1724 if (format != NULL) {
1725 set_output_format(oparms, sample_format_map[i].shortformat);
1726 }
1727 }
1728 }
1729
csoundGetOutputFormat(CSOUND * csound,char * type,char * format)1730 PUBLIC void csoundGetOutputFormat(CSOUND *csound,
1731 char *type, char *format)
1732 {
1733
1734 OPARMS *oparms = csound->oparms;
1735 int i = 0;
1736 const char* fmt = get_output_format(oparms);
1737 while (file_type_map[i].type != oparms->filetyp &&
1738 file_type_map[i].format != NULL) i++;
1739 if(file_type_map[i].format != NULL)
1740 strcpy(type,file_type_map[i].format);
1741 else
1742 strcpy(type,"");
1743 if(fmt != NULL)
1744 strcpy(format, fmt);
1745 else
1746 strcpy(format,"");
1747 }
1748
1749
1750
csoundSetInput(CSOUND * csound,const char * name)1751 PUBLIC void csoundSetInput(CSOUND *csound, const char *name) {
1752 OPARMS *oparms = csound->oparms;
1753
1754 /* if already compiled and running, return */
1755 if (csound->engineStatus & CS_STATE_COMP) return;
1756
1757 oparms->infilename =
1758 csound->Malloc(csound, strlen(name)); /* will be freed by memRESET */
1759 strcpy(oparms->infilename, name);
1760 if (strcmp(oparms->infilename, "stdin") == 0) {
1761 set_stdin_assign(csound, STDINASSIGN_SNDFILE, 1);
1762 #if defined(WIN32)
1763 csound->Warning(csound, Str("stdin not supported on this platform"));
1764 #endif
1765 }
1766 else
1767 set_stdin_assign(csound, STDINASSIGN_SNDFILE, 0);
1768 oparms->sfread = 1;
1769 }
1770
csoundSetMIDIInput(CSOUND * csound,const char * name)1771 PUBLIC void csoundSetMIDIInput(CSOUND *csound, const char *name) {
1772 OPARMS *oparms = csound->oparms;
1773
1774 /* if already compiled and running, return */
1775 if (csound->engineStatus & CS_STATE_COMP) return;
1776
1777 oparms->Midiname =
1778 csound->Malloc(csound, strlen(name)); /* will be freed by memRESET */
1779 strcpy(oparms->Midiname, name);
1780 if (!strcmp(oparms->Midiname, "stdin")) {
1781 set_stdin_assign(csound, STDINASSIGN_MIDIDEV, 1);
1782 #if defined(WIN32)
1783 csound->Warning(csound, Str("stdin not supported on this platform"));
1784 #endif
1785 }
1786 else
1787 set_stdin_assign(csound, STDINASSIGN_MIDIDEV, 0);
1788 oparms->Midiin = 1;
1789 }
1790
csoundSetMIDIFileInput(CSOUND * csound,const char * name)1791 PUBLIC void csoundSetMIDIFileInput(CSOUND *csound, const char *name) {
1792 OPARMS *oparms = csound->oparms;
1793
1794 /* if already compiled and running, return */
1795 if (csound->engineStatus & CS_STATE_COMP) return;
1796
1797 oparms->FMidiname =
1798 csound->Malloc(csound, strlen(name)); /* will be freed by memRESET */
1799 strcpy(oparms->FMidiname, name);
1800 if (!strcmp(oparms->FMidiname, "stdin")) {
1801 set_stdin_assign(csound, STDINASSIGN_MIDIFILE, 1);
1802 #if defined(WIN32)
1803 csound->Warning(csound, Str("stdin not supported on this platform"));
1804 #endif
1805 }
1806 else
1807 set_stdin_assign(csound, STDINASSIGN_MIDIFILE, 0);
1808 oparms->FMidiin = 1;
1809 }
1810
csoundSetMIDIFileOutput(CSOUND * csound,const char * name)1811 PUBLIC void csoundSetMIDIFileOutput(CSOUND *csound, const char *name) {
1812 OPARMS *oparms = csound->oparms;
1813
1814 /* if already compiled and running, return */
1815 if (csound->engineStatus & CS_STATE_COMP) return;
1816
1817 oparms->FMidioutname =
1818 csound->Malloc(csound, strlen(name)); /* will be freed by memRESET */
1819 strcpy(oparms->FMidioutname, name);
1820 }
1821
csoundSetMIDIOutput(CSOUND * csound,const char * name)1822 PUBLIC void csoundSetMIDIOutput(CSOUND *csound, const char *name) {
1823 OPARMS *oparms = csound->oparms;
1824
1825 /* if already compiled and running, return */
1826 if (csound->engineStatus & CS_STATE_COMP) return;
1827
1828 oparms->Midioutname =
1829 csound->Malloc(csound, strlen(name)); /* will be freed by memRESET */
1830 strcpy(oparms->Midioutname, name);
1831 }
1832
list_audio_devices(CSOUND * csound,int output)1833 static void list_audio_devices(CSOUND *csound, int output){
1834
1835 int i,n = csoundGetAudioDevList(csound,NULL, output);
1836 CS_AUDIODEVICE *devs = (CS_AUDIODEVICE *)
1837 csound->Malloc(csound, n*sizeof(CS_AUDIODEVICE));
1838 if (output)
1839 csound->MessageS(csound,CSOUNDMSG_STDOUT,
1840 Str("%d audio output devices\n"), n);
1841 else
1842 csound->MessageS(csound, CSOUNDMSG_STDOUT,
1843 Str("%d audio input devices\n"), n);
1844 csoundGetAudioDevList(csound,devs,output);
1845 for (i=0; i < n; i++)
1846 csound->Message(csound, " %d: %s (%s)\n",
1847 i, devs[i].device_id, devs[i].device_name);
1848 csound->Free(csound, devs);
1849 }
1850
list_midi_devices(CSOUND * csound,int output)1851 static void list_midi_devices(CSOUND *csound, int output){
1852
1853 int i,n = csoundGetMIDIDevList(csound,NULL, output);
1854 CS_MIDIDEVICE *devs =
1855 (CS_MIDIDEVICE *) csound->Malloc(csound, n*sizeof(CS_MIDIDEVICE));
1856 if (output)
1857 csound->MessageS(csound, CSOUNDMSG_STDOUT,
1858 Str("%d MIDI output devices\n"), n);
1859 else
1860 csound->MessageS(csound, CSOUNDMSG_STDOUT,
1861 Str("%d MIDI input devices\n"), n);
1862 csoundGetMIDIDevList(csound,devs,output);
1863 for (i=0; i < n; i++)
1864 csound->Message(csound, " %d: %s (%s)\n",
1865 i, devs[i].device_id, devs[i].device_name);
1866 csound->Free(csound, devs);
1867 }
1868