2 SuperCollider real time audio synthesis system
3 Copyright (c) 2002 James McCartney. All rights reserved.
4 http://www.audiosynth.com
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 #include "SC_WorldOptions.h"
33 # include <winsock2.h>
35 # include <sys/wait.h>
40 // according to this page: http://www.mkssoftware.com/docs/man3/setlinebuf.3.asp
41 // setlinebuf is equivalent to the setvbuf call below.
42 inline int setlinebuf(FILE *stream
)
44 return setvbuf( stream
, (char*)0, _IONBF
, 0 );
54 "supercollider_synth options:\n"
55 " -u <udp-port-number> a port number 0-65535\n"
56 " -t <tcp-port-number> a port number 0-65535\n"
57 " -c <number-of-control-bus-channels> (default %d)\n"
58 " -a <number-of-audio-bus-channels> (default %d)\n"
59 " -i <number-of-input-bus-channels> (default %d)\n"
60 " -o <number-of-output-bus-channels> (default %d)\n"
61 " -z <block-size> (default %d)\n"
62 " -Z <hardware-buffer-size> (default %d)\n"
63 " -S <hardware-sample-rate> (default %d)\n"
64 " -b <number-of-sample-buffers> (default %d)\n"
65 " -n <max-number-of-nodes> (default %d)\n"
66 " -d <max-number-of-synth-defs> (default %d)\n"
67 " -m <real-time-memory-size> (default %d)\n"
68 " -w <number-of-wire-buffers> (default %d)\n"
69 " -r <number-of-random-seeds> (default %d)\n"
70 " -D <load synthdefs? 1 or 0> (default %d)\n"
71 " -R <publish to Rendezvous? 1 or 0> (default %d)\n"
72 " -l <max-logins> (default %d)\n"
73 " maximum number of named return addresses stored\n"
74 " also maximum number of tcp connections accepted\n"
75 " -p <session-password>\n"
76 " When using TCP, the session password must be the first command sent.\n"
77 " The default is no password.\n"
78 " UDP ports never require passwords, so for security use TCP.\n"
79 " -N <cmd-filename> <input-filename> <output-filename> <sample-rate> <header-format> <sample-format>\n"
81 " -I <input-streams-enabled>\n"
82 " -O <output-streams-enabled>\n"
84 #if (_POSIX_MEMLOCK - 0) >= 200112L
85 " -L enable memory locking\n"
87 " -H <hardware-device-name>\n"
89 " 0 is normal behaviour\n"
90 " -1 suppresses informational messages\n"
91 " -2 suppresses informational and many error messages\n"
92 " -U <ugen-plugins-path> a colon-separated list of paths\n"
93 " if -U is specified, the standard paths are NOT searched for plugins.\n"
94 " -P <restricted-path> \n"
95 " if specified, prevents file-accessing OSC commands from\n"
96 " accessing files outside <restricted-path>.\n"
97 "\nTo quit, send a 'quit' command via UDP or TCP, or press ctrl-C.\n\n",
98 kDefaultWorldOptions
.mNumControlBusChannels
,
99 kDefaultWorldOptions
.mNumAudioBusChannels
,
100 kDefaultWorldOptions
.mNumInputBusChannels
,
101 kDefaultWorldOptions
.mNumOutputBusChannels
,
102 kDefaultWorldOptions
.mBufLength
,
103 kDefaultWorldOptions
.mPreferredHardwareBufferFrameSize
,
104 kDefaultWorldOptions
.mPreferredSampleRate
,
105 kDefaultWorldOptions
.mNumBuffers
,
106 kDefaultWorldOptions
.mMaxNodes
,
107 kDefaultWorldOptions
.mMaxGraphDefs
,
108 kDefaultWorldOptions
.mRealTimeMemorySize
,
109 kDefaultWorldOptions
.mMaxWireBufs
,
110 kDefaultWorldOptions
.mNumRGens
,
111 kDefaultWorldOptions
.mRendezvous
,
112 kDefaultWorldOptions
.mLoadGraphDefs
,
113 kDefaultWorldOptions
.mMaxLogins
118 #define checkNumArgs(n) \
120 if (n == 2) scprintf("ERROR: Argument expected after option %s\n", argv[j]); \
121 else scprintf("ERROR: More arguments expected after option %s\n", argv[j]); \
127 int main(int argc
, char* argv
[]);
128 int main(int argc
, char* argv
[])
133 #ifdef SC_WIN32_STATIC_PTHREADS
134 // initialize statically linked pthreads library
135 pthread_win32_process_attach_np();
138 // initialize winsock
141 if ((nCode
= WSAStartup(MAKEWORD(1, 1), &wsaData
)) != 0) {
142 scprintf( "WSAStartup() failed with error code %d.\n", nCode
);
150 WorldOptions options
= kDefaultWorldOptions
;
152 for (int i
=1; i
<argc
;) {
153 if (argv
[i
][0] != '-' || argv
[i
][1] == 0 || strchr("utaioczblndpmwZrNSDIOMHvRUhPL", argv
[i
][1]) == 0) {
154 scprintf("ERROR: Invalid option %s\n", argv
[i
]);
158 switch (argv
[j
][1]) {
161 udpPortNum
= atoi(argv
[j
+1]);
165 tcpPortNum
= atoi(argv
[j
+1]);
169 options
.mNumAudioBusChannels
= atoi(argv
[j
+1]);
173 options
.mNumInputBusChannels
= atoi(argv
[j
+1]);
177 options
.mNumOutputBusChannels
= atoi(argv
[j
+1]);
181 options
.mNumControlBusChannels
= atoi(argv
[j
+1]);
185 options
.mBufLength
= NEXTPOWEROFTWO(atoi(argv
[j
+1]));
189 options
.mPreferredHardwareBufferFrameSize
= NEXTPOWEROFTWO(atoi(argv
[j
+1]));
193 options
.mNumBuffers
= NEXTPOWEROFTWO(atoi(argv
[j
+1]));
197 options
.mMaxLogins
= NEXTPOWEROFTWO(atoi(argv
[j
+1]));
201 options
.mMaxNodes
= NEXTPOWEROFTWO(atoi(argv
[j
+1]));
205 options
.mMaxGraphDefs
= NEXTPOWEROFTWO(atoi(argv
[j
+1]));
209 options
.mPassword
= argv
[j
+1];
213 options
.mRealTimeMemorySize
= atoi(argv
[j
+1]);
217 options
.mMaxWireBufs
= atoi(argv
[j
+1]);
221 options
.mNumRGens
= atoi(argv
[j
+1]);
225 options
.mPreferredSampleRate
= (uint32
)atof(argv
[j
+1]);
229 options
.mLoadGraphDefs
= atoi(argv
[j
+1]);
233 scprintf("NRT mode not supported: scsynth compiled without libsndfile\n");
236 // -N cmd-filename input-filename output-filename sample-rate header-format sample-format
238 options
.mRealTime
= false;
239 options
.mNonRealTimeCmdFilename
= strcmp(argv
[j
+1], "_") ? argv
[j
+1] : 0;
240 options
.mNonRealTimeInputFilename
= strcmp(argv
[j
+2], "_") ? argv
[j
+2] : 0;
241 options
.mNonRealTimeOutputFilename
= argv
[j
+3];
242 options
.mPreferredSampleRate
= (uint32
)atof(argv
[j
+4]);
243 options
.mNonRealTimeOutputHeaderFormat
= argv
[j
+5];
244 options
.mNonRealTimeOutputSampleFormat
= argv
[j
+6];
249 options
.mInputStreamsEnabled
= argv
[j
+1];
253 options
.mOutputStreamsEnabled
= argv
[j
+1];
259 options
.mInDeviceName
= argv
[j
+1];
261 if (i
+1>argc
|| argv
[j
+2][0]=='-')
263 options
.mOutDeviceName
= options
.mInDeviceName
;
267 // If there's a second argument then the user wants separate I/O devices
268 options
.mOutDeviceName
= argv
[j
+2];
272 options
.mOutDeviceName
= options
.mInDeviceName
; // Non-Mac platforms always use same device
277 #if (_POSIX_MEMLOCK - 0) >= 200112L
278 options
.mMemoryLocking
= true;
280 options
.mMemoryLocking
= false;
285 options
.mVerbosity
= atoi(argv
[j
+1]);
289 options
.mRendezvous
= atoi(argv
[j
+1]) > 0;
293 options
.mUGensPluginPath
= argv
[j
+1];
297 options
.mRestrictedPath
= argv
[j
+1];
303 if (udpPortNum
== -1 && tcpPortNum
== -1 && options
.mRealTime
) {
304 scprintf("ERROR: There must be a -u and/or a -t options, or -N for nonrealtime.\n");
307 if (options
.mNumInputBusChannels
+ options
.mNumOutputBusChannels
> options
.mNumAudioBusChannels
) {
308 scprintf("ERROR: number of audio bus channels < inputs + outputs.\n");
312 if (options
.mRealTime
) {
313 int port
= (udpPortNum
> 0) ? udpPortNum
316 options
.mSharedMemoryID
= port
;
318 options
.mSharedMemoryID
= 0;
321 struct World
*world
= World_New(&options
);
322 if (!world
) return 1;
324 if (!options
.mRealTime
) {
330 World_NonRealTimeSynthesis(world
, &options
);
331 } catch (std::exception
& exc
) {
332 scprintf("%s\n", exc
.what());
339 if (udpPortNum
>= 0) {
340 if (!World_OpenUDP(world
, udpPortNum
)) {
341 World_Cleanup(world
);
345 if (tcpPortNum
>= 0) {
346 if (!World_OpenTCP(world
, tcpPortNum
, options
.mMaxLogins
, 8)) {
347 World_Cleanup(world
);
352 if(options
.mVerbosity
>=0){
354 scprintf("SuperCollider 3 server ready.\n");
356 scprintf("SuperCollider 3 server ready (debug build).\n");
361 World_WaitForQuit(world
);
368 #ifdef SC_WIN32_STATIC_PTHREADS
369 // clean up statically linked pthreads
370 pthread_win32_process_detach_np();
371 #endif // SC_WIN32_STATIC_PTHREADS