34
34
#include <unistd.h>
35
35
#include <stdlib.h>
36
36
#include <string.h>
38
39
extern int inet_aton(const char *cp, struct in_addr *inp);
42
43
MYFLT *asig, *ipaddress, *port, *buffersize;
46
49
struct sockaddr_in server_addr;
51
54
MYFLT *asigl, *asigr, *ipaddress, *port, *buffersize;
55
60
struct sockaddr_in server_addr;
61
66
static int init_send(CSOUND *csound, SOCKSEND *p)
69
int bwidth = sizeof(MYFLT);
71
WSADATA wsaData = {0};
73
if ((err=WSAStartup(MAKEWORD(2,2), &wsaData))!= 0)
74
csound->InitError(csound, Str("Winsock2 failed to start: %d"), err);
76
p->ff = (int)(*p->format);
65
77
p->bsize = bsize = (int) *p->buffersize;
66
if (UNLIKELY((sizeof(MYFLT) * bsize) > MTU)) {
67
return csound->InitError(csound, Str("The buffersize must be <= %d samples "
68
"to fit in a udp-packet."),
69
(int) (MTU / sizeof(MYFLT)));
78
/* if (UNLIKELY((sizeof(MYFLT) * bsize) > MTU)) { */
79
/* return csound->InitError(csound, Str("The buffersize must be <= %d samples " */
80
/* "to fit in a udp-packet."), */
81
/* (int) (MTU / sizeof(MYFLT))); */
73
p->sock = socket(PF_INET, SOCK_DGRAM, 0);
85
p->sock = socket(AF_INET, SOCK_DGRAM, 0);
74
86
if (UNLIKELY(p->sock < 0)) {
75
87
return csound->InitError(csound, Str("creating socket"));
77
89
/* create server address: where we want to send to and clear it out */
78
90
memset(&p->server_addr, 0, sizeof(p->server_addr));
79
91
p->server_addr.sin_family = AF_INET; /* it is an INET address */
93
p->server_addr.sin_addr.S_un.S_addr = inet_addr((const char *) p->ipaddress);
80
95
inet_aton((const char *) p->ipaddress,
81
96
&p->server_addr.sin_addr); /* the server IP address */
82
98
p->server_addr.sin_port = htons((int) *p->port); /* the port */
100
if (p->ff) bwidth = sizeof(int16);
84
101
/* create a buffer to write the interleaved audio to */
85
if (p->aux.auxp == NULL || (long) (bsize * sizeof(MYFLT)) > p->aux.size)
102
if (p->aux.auxp == NULL || (long) (bsize * bwidth) > p->aux.size)
86
103
/* allocate space for the buffer */
87
csound->AuxAlloc(csound, (bsize * sizeof(MYFLT)), &p->aux);
104
csound->AuxAlloc(csound, (bsize * bwidth), &p->aux);
89
memset(p->aux.auxp, 0, sizeof(MYFLT) * bsize);
106
memset(p->aux.auxp, 0, bwidth * bsize);
98
116
int buffersize = p->bsize;
99
117
MYFLT *asig = p->asig;
100
118
MYFLT *out = (MYFLT *) p->aux.auxp;
119
int16 *outs = (int16 *) p->aux.auxp;
102
122
for (i = 0, wp = p->wp; i < ksmps; i++, wp++) {
103
123
if (wp == buffersize) {
104
124
/* send the package when we have a full buffer */
105
if (UNLIKELY(sendto(p->sock, out, buffersize * sizeof(MYFLT), 0, to,
125
if (UNLIKELY(sendto(p->sock, (void*)out, buffersize * p->bwidth, 0, to,
106
126
sizeof(p->server_addr)) < 0)) {
107
127
return csound->PerfError(csound, Str("sendto failed"));
131
if (ff) { // Scale for 0dbfs and make LE
132
int16 val = (int16)((32768.0*asig[i])/csound->e0dbfs);
137
ch.benchar[0] = 0xFF & val;
138
ch.benchar[1] = 0xFF & (val >> 8);
139
outs[wp] = ch.bensht;
119
150
static int init_sendS(CSOUND *csound, SOCKSENDS *p)
153
int bwidth = sizeof(MYFLT);
155
WSADATA wsaData = {0};
157
if ((err=WSAStartup(MAKEWORD(2,2), &wsaData))!= 0)
158
csound->InitError(csound, Str("Winsock2 failed to start: %d"), err);
161
p->ff = (int)(*p->format);
123
162
p->bsize = bsize = (int) *p->buffersize;
124
if (UNLIKELY((sizeof(MYFLT) * bsize) > MTU)) {
125
return csound->InitError(csound, Str("The buffersize must be <= %d samples "
126
"to fit in a udp-packet."),
127
(int) (MTU / sizeof(MYFLT)));
163
/* if (UNLIKELY((sizeof(MYFLT) * bsize) > MTU)) { */
164
/* return csound->InitError(csound, Str("The buffersize must be <= %d samples " */
165
/* "to fit in a udp-packet."), */
166
/* (int) (MTU / sizeof(MYFLT))); */
131
170
p->sock = socket(AF_INET, SOCK_DGRAM, 0);
135
174
/* create server address: where we want to send to and clear it out */
136
175
memset(&p->server_addr, 0, sizeof(p->server_addr));
137
176
p->server_addr.sin_family = AF_INET; /* it is an INET address */
178
p->server_addr.sin_addr.S_un.S_addr = inet_addr((const char *) p->ipaddress);
138
180
inet_aton((const char *) p->ipaddress,
139
181
&p->server_addr.sin_addr); /* the server IP address */
140
183
p->server_addr.sin_port = htons((int) *p->port); /* the port */
185
if (p->ff) bwidth = sizeof(int16);
142
186
/* create a buffer to write the interleaved audio to */
143
if (p->aux.auxp == NULL || (long) (bsize * sizeof(MYFLT)) > p->aux.size)
187
if (p->aux.auxp == NULL || (long) (bsize * bwidth) > p->aux.size)
144
188
/* allocate space for the buffer */
145
csound->AuxAlloc(csound, (bsize * sizeof(MYFLT)), &p->aux);
189
csound->AuxAlloc(csound, (bsize * bwidth), &p->aux);
147
memset(p->aux.auxp, 0, sizeof(MYFLT) * bsize);
191
memset(p->aux.auxp, 0, bwidth * bsize);
155
200
MYFLT *asigl = p->asigl;
156
201
MYFLT *asigr = p->asigr;
157
202
MYFLT *out = (MYFLT *) p->aux.auxp;
203
int16 *outs = (int16 *) p->aux.auxp;
159
205
int buffersize = p->bsize;
160
206
int wp, ksmps = csound->ksmps;
162
209
/* store the samples of the channels interleaved in the packet */
163
210
/* (left, right) */
164
211
for (i = 0, wp = p->wp; i < ksmps; i++, wp += 2) {
165
212
if (wp == buffersize) {
166
213
/* send the package when we have a full buffer */
167
if (UNLIKELY(sendto(p->sock, out, buffersize * sizeof(MYFLT), 0, to,
214
if (UNLIKELY(sendto(p->sock, (void*)out, buffersize * p->bwidth, 0, to,
168
215
sizeof(p->server_addr)) < 0)) {
169
216
return csound->PerfError(csound, Str("sendto failed"));
174
out[wp + 1] = asigr[i];
220
if (ff) { // Scale for 0dbfs and make LE
221
int16 val = 0x8000*(asigl[i]/csound->e0dbfs);
227
ch.benchar[0] = 0xFF & val;
228
ch.benchar[1] = 0xFF & (val >> 8);
229
outs[wp] = ch.bensht;
230
val = 0x8000*(asigl[i+1]/csound->e0dbfs);
231
ch.benchar[0] = 0xFF & val;
232
ch.benchar[1] = 0xFF & (val >> 8);
233
outs[wp + 1] = ch.bensht;
237
out[wp + 1] = asigr[i];
181
245
/* TCP version */
182
246
static int init_ssend(CSOUND *csound, SOCKSEND *p)
249
WSADATA wsaData = {0};
251
if ((err=WSAStartup(MAKEWORD(2,2), &wsaData))!= 0)
252
csound->InitError(csound, Str("Winsock2 failed to start: %d"), err);
186
255
/* create a STREAM (TCP) socket in the INET (IP) protocol */
187
256
p->sock = socket(PF_INET, SOCK_STREAM, 0);
199
268
p->server_addr.sin_family = AF_INET;
201
270
/* the server IP address, in network byte order */
272
p->server_addr.sin_addr.S_un.S_addr = inet_addr((const char *) p->ipaddress);
202
274
inet_aton((const char *) p->ipaddress, &(p->server_addr.sin_addr));
204
277
/* the port we are going to listen on, in network byte order */
205
278
p->server_addr.sin_port = htons((int) *p->port);
207
/* associate the socket with the address and port */
209
(p->sock, (struct sockaddr *) &p->server_addr, sizeof(p->server_addr))
211
return csound->InitError(csound, Str("bind failed"));
214
/* start the socket listening for new connections -- may wait */
215
if (UNLIKELY(listen(p->sock, 5) < 0)) {
216
return csound->InitError(csound, Str("listen failed"));
218
clilen = sizeof(p->server_addr);
219
p->conn = accept(p->sock, (struct sockaddr *) &p->server_addr, &clilen);
221
if (UNLIKELY(p->conn < 0)) {
222
return csound->InitError(csound, Str("accept failed"));
281
if (connect(p->sock, (struct sockaddr *) &p->server_addr,
282
sizeof(p->server_addr)) < 0) {
284
if (errno == ECONNREFUSED)
287
return csound->InitError(csound, Str("connect failed (%d)"), errno);
229
295
int n = sizeof(MYFLT) * csound->ksmps;
231
if (UNLIKELY(n != write(p->conn, p->asig, sizeof(MYFLT) * csound->ksmps))) {
297
if (n != write(p->sock, p->asig, n)) {
298
csound->Message(csound, "Expected %d got %d\n",
299
(int) (sizeof(MYFLT) * csound->ksmps), n);
232
300
return csound->PerfError(csound, Str("write to socket failed"));
237
306
#define S(x) sizeof(x)
239
static OENTRY localops[] = {
240
{ "socksend", S(SOCKSEND), 5, "", "aSii", (SUBR) init_send, NULL,
308
static OENTRY socksend_localops[] = {
309
{ "socksend", S(SOCKSEND), 5, "", "aSiio", (SUBR) init_send, NULL,
241
310
(SUBR) send_send },
242
{ "socksends", S(SOCKSENDS), 5, "", "aaSii", (SUBR) init_sendS, NULL,
311
{ "socksends", S(SOCKSENDS), 5, "", "aaSiio", (SUBR) init_sendS, NULL,
243
312
(SUBR) send_sendS },
244
313
{ "stsend", S(SOCKSEND), 5, "", "aSi", (SUBR) init_ssend, NULL,
245
314
(SUBR) send_ssend }
317
LINKAGE1(socksend_localops)