2 SuperColliderAU Copyright (c) 2006 Gerard Roma.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 #include "SCProcess.h"
21 void* scThreadFunc(void* arg
);
23 void* scThreadFunc(void* arg
)
25 World
* world
= (World
*)arg
;
26 World_WaitForQuit(world
);
30 void null_reply_func(struct ReplyAddress
* /*addr*/, char* /*msg*/, int /*size*/);
32 SCProcess::SCProcess()
37 int SCProcess::findNextFreeUdpPort(int startNum
){
38 int server_socket
= -1;
39 struct sockaddr_in mBindSockAddr
;
42 if ((server_socket
= socket(AF_INET
, SOCK_DGRAM
, 0)) < 0) {
43 scprintf("failed to create udp socket\n");
47 bzero((char *)&mBindSockAddr
, sizeof(mBindSockAddr
));
48 mBindSockAddr
.sin_family
= AF_INET
;
49 mBindSockAddr
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
50 mBindSockAddr
.sin_port
= htons(port
);
52 setsockopt( server_socket
, SOL_SOCKET
, SO_REUSEADDR
, &on
, sizeof(on
));
54 while (bind(server_socket
, (struct sockaddr
*)&mBindSockAddr
, sizeof(mBindSockAddr
)) < 0) {
55 if(--numberOfTries
<0 || (errno
!= EADDRINUSE
)) {
56 scprintf("unable to bind udp socket\n");
60 mBindSockAddr
.sin_port
= htons(port
);
67 void SCProcess::startUp(WorldOptions options
, CFStringRef pluginsPath
, CFStringRef synthdefsPath
, int preferredPort
){
70 char stringBuffer
[PATH_MAX
] ;
73 CFStringGetCString(pluginsPath
, stringBuffer
, sizeof(stringBuffer
), kCFStringEncodingUTF8
);
74 setenv("SC_PLUGIN_PATH", stringBuffer
, 1);
75 CFStringGetCString(synthdefsPath
, stringBuffer
, sizeof(stringBuffer
), kCFStringEncodingUTF8
);
76 setenv("SC_SYNTHDEF_PATH", stringBuffer
, 1);
77 this->portNum
= findNextFreeUdpPort(preferredPort
);
78 world
= World_New(&options
);
81 if (this->portNum
>= 0) World_OpenUDP(world
, this->portNum
);
82 pthread_create (&scThread
, NULL
, scThreadFunc
, (void*)world
);
85 small_scpacket packet
= messages
.initTreeMessage();
86 World_SendPacket(world
, 16, (char*)packet
.buf
, null_reply_func
);
91 void SCProcess::makeSynth(){
94 small_scpacket packet
;
95 size_t messageSize
= messages
.createSynthMessage(&packet
, synthName
);
96 World_SendPacket(world
,messageSize
, (char*)packet
.buf
, null_reply_func
);
100 void SCProcess::sendParamChangeMessage(CFStringRef name
, float value
){
101 OSCMessages messages
;
103 small_scpacket packet
;
104 size_t messageSize
=messages
.parameterMessage(&packet
, name
,value
);
105 World_SendPacket(world
, messageSize
, (char*)packet
.buf
, null_reply_func
);
109 void SCProcess::sendTick(int64 oscTime
, int bus
){
110 OSCMessages messages
;
111 small_scpacket packet
= messages
.sendTickMessage(oscTime
, bus
);
112 World_SendPacket(world
, 40, (char*)packet
.buf
, null_reply_func
);
116 void SCProcess::sendNote(int64 oscTime
, int note
, int velocity
){
117 OSCMessages messages
;
118 small_scpacket packet
= messages
.noteMessage(oscTime
, note
, velocity
);
119 World_SendPacket(world
, 92, (char*)packet
.buf
, null_reply_func
);
123 void SCProcess::run(const AudioBufferList
* in
, AudioBufferList
* out
, UInt32 inFramesToProcess
, AudioTimeStamp inTimeStamp
, Float64 sampleRate
, int64 oscTime
){
124 if (world
->mRunning
){
125 SC_AUAudioDriver
* driver
= (SC_AUAudioDriver
*)this->world
->hw
->mAudioDriver
;
126 //AUCallback(driver,(AudioBufferList*)in, out, &inTimeStamp, inFramesToProcess, sampleRate, oscTime );
127 driver
->Callback(in
, out
, &inTimeStamp
, inFramesToProcess
, sampleRate
, oscTime
);
131 void SCProcess::quit(){
132 OSCMessages messages
;
133 if (world
&& world
->mRunning
){
134 small_scpacket packet
= messages
.quitMessage();
135 World_SendPacket(world
, 8,(char*)packet
.buf
, null_reply_func
);