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