~ubuntu-branches/ubuntu/precise/csound/precise

« back to all changes in this revision

Viewing changes to Opcodes/socksend.c

  • Committer: Package Import Robot
  • Author(s): Felipe Sateler
  • Date: 2012-04-19 09:26:46 UTC
  • mfrom: (3.2.19 sid)
  • Revision ID: package-import@ubuntu.com-20120419092646-96xbj1n6atuqosk2
Tags: 1:5.17.6~dfsg-1
* New upstream release
 - Do not build the wiimote opcodes (we need wiiuse).
* Add new API function to symbols file
* Disable lua opcodes, they were broken. Requires OpenMP to be enabled.
* Backport fixes from upstream:
  - Link dssi4cs with dl. Backport
  - Fix building of CsoundAC

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
 
24
24
#include "csdl.h"
25
25
#include <sys/types.h>
26
 
#ifdef __OS_WINDOWS__
 
26
#ifdef WIN32
27
27
#include <winsock2.h>
28
28
#include <ws2tcpip.h>
29
29
#else
34
34
#include <unistd.h>
35
35
#include <stdlib.h>
36
36
#include <string.h>
 
37
#include <errno.h>
37
38
 
38
39
extern  int     inet_aton(const char *cp, struct in_addr *inp);
39
40
 
40
41
typedef struct {
41
42
    OPDS    h;
42
43
    MYFLT   *asig, *ipaddress, *port, *buffersize;
 
44
    MYFLT   *format;
43
45
    AUXCH   aux;
44
 
    int     sock, conn;
 
46
    int     sock;
45
47
    int     bsize, wp;
 
48
    int     ff, bwidth;
46
49
    struct sockaddr_in server_addr;
47
50
} SOCKSEND;
48
51
 
49
52
typedef struct {
50
53
    OPDS    h;
51
54
    MYFLT   *asigl, *asigr, *ipaddress, *port, *buffersize;
 
55
    MYFLT   *format;
52
56
    AUXCH   aux;
53
 
    int     sock, conn;
 
57
    int     sock;
54
58
    int     bsize, wp;
 
59
    int     ff, bwidth;
55
60
    struct sockaddr_in server_addr;
56
61
} SOCKSENDS;
57
62
 
61
66
static int init_send(CSOUND *csound, SOCKSEND *p)
62
67
{
63
68
    int     bsize;
64
 
 
 
69
    int     bwidth = sizeof(MYFLT);
 
70
#ifdef WIN32
 
71
    WSADATA wsaData = {0};
 
72
    int err;
 
73
    if ((err=WSAStartup(MAKEWORD(2,2), &wsaData))!= 0)
 
74
      csound->InitError(csound, Str("Winsock2 failed to start: %d"), err);
 
75
#endif
 
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)));
70
 
    }
 
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))); */
 
82
    /* } */
71
83
    p->wp = 0;
72
84
 
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"));
76
88
    }
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 */
 
92
#ifdef WIN32
 
93
    p->server_addr.sin_addr.S_un.S_addr = inet_addr((const char *) p->ipaddress);
 
94
#else
80
95
    inet_aton((const char *) p->ipaddress,
81
96
              &p->server_addr.sin_addr);    /* the server IP address */
 
97
#endif
82
98
    p->server_addr.sin_port = htons((int) *p->port);    /* the port */
83
99
 
 
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);
88
105
    else {
89
 
      memset(p->aux.auxp, 0, sizeof(MYFLT) * bsize);
 
106
      memset(p->aux.auxp, 0, bwidth * bsize);
90
107
    }
 
108
    p->bwidth = bwidth;
91
109
    return OK;
92
110
}
93
111
 
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;
 
120
    int     ff = p->ff;
101
121
 
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"));
108
128
        }
109
129
        wp = 0;
110
130
      }
111
 
      out[wp] = asig[i];
 
131
      if (ff) { // Scale for 0dbfs and make LE
 
132
        int16 val = (int16)((32768.0*asig[i])/csound->e0dbfs);
 
133
        union cheat {
 
134
          char  benchar[2];
 
135
          int16 bensht;
 
136
        } ch;
 
137
        ch.benchar[0] = 0xFF & val;
 
138
        ch.benchar[1] = 0xFF & (val >> 8);
 
139
        outs[wp] = ch.bensht;
 
140
      }
 
141
      else
 
142
       out[wp] = asig[i];
112
143
    }
113
144
    p->wp = wp;
114
145
 
119
150
static int init_sendS(CSOUND *csound, SOCKSENDS *p)
120
151
{
121
152
    int     bsize;
 
153
    int     bwidth = sizeof(MYFLT);
 
154
#ifdef WIN32
 
155
    WSADATA wsaData = {0};
 
156
    int err;
 
157
    if ((err=WSAStartup(MAKEWORD(2,2), &wsaData))!= 0)
 
158
      csound->InitError(csound, Str("Winsock2 failed to start: %d"), err);
 
159
#endif
122
160
 
 
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)));
128
 
    }
 
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))); */
 
167
    /* } */
129
168
    p->wp = 0;
130
169
 
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 */
 
177
#ifdef WIN32
 
178
    p->server_addr.sin_addr.S_un.S_addr = inet_addr((const char *) p->ipaddress);
 
179
#else
138
180
    inet_aton((const char *) p->ipaddress,
139
181
              &p->server_addr.sin_addr);    /* the server IP address */
 
182
#endif
140
183
    p->server_addr.sin_port = htons((int) *p->port);    /* the port */
141
184
 
 
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);
146
190
    else {
147
 
      memset(p->aux.auxp, 0, sizeof(MYFLT) * bsize);
 
191
      memset(p->aux.auxp, 0, bwidth * bsize);
148
192
    }
 
193
    p->bwidth = bwidth;
149
194
    return OK;
150
195
}
151
196
 
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;
158
204
    int     i;
159
205
    int     buffersize = p->bsize;
160
206
    int     wp, ksmps = csound->ksmps;
 
207
    int     ff = p->ff;
161
208
 
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"));
170
217
        }
171
218
        wp = 0;
172
219
      }
173
 
      out[wp] = asigl[i];
174
 
      out[wp + 1] = asigr[i];
 
220
      if (ff) { // Scale for 0dbfs and make LE
 
221
        int16 val = 0x8000*(asigl[i]/csound->e0dbfs);
 
222
        union {
 
223
          char  benchar[2];
 
224
          int16 bensht;
 
225
        } ch;
 
226
 
 
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;
 
234
      }
 
235
      else {
 
236
        out[wp] = asigl[i];
 
237
        out[wp + 1] = asigr[i];
 
238
      }
175
239
    }
176
240
    p->wp = wp;
177
241
 
181
245
/* TCP version */
182
246
static int init_ssend(CSOUND *csound, SOCKSEND *p)
183
247
{
184
 
    socklen_t clilen;
 
248
#ifdef WIN32
 
249
    WSADATA wsaData = {0};
 
250
    int err;
 
251
    if ((err=WSAStartup(MAKEWORD(2,2), &wsaData))!= 0)
 
252
      csound->InitError(csound, Str("Winsock2 failed to start: %d"), err);
 
253
#endif
185
254
 
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;
200
269
 
201
270
    /* the server IP address, in network byte order */
 
271
#ifdef WIN32
 
272
    p->server_addr.sin_addr.S_un.S_addr = inet_addr((const char *) p->ipaddress);
 
273
#else
202
274
    inet_aton((const char *) p->ipaddress, &(p->server_addr.sin_addr));
 
275
#endif
203
276
 
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);
206
279
 
207
 
    /* associate the socket with the address and port */
208
 
    if (UNLIKELY(bind
209
 
        (p->sock, (struct sockaddr *) &p->server_addr, sizeof(p->server_addr))
210
 
                 < 0)) {
211
 
      return csound->InitError(csound, Str("bind failed"));
212
 
    }
213
 
 
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"));
217
 
    }
218
 
    clilen = sizeof(p->server_addr);
219
 
    p->conn = accept(p->sock, (struct sockaddr *) &p->server_addr, &clilen);
220
 
 
221
 
    if (UNLIKELY(p->conn < 0)) {
222
 
      return csound->InitError(csound, Str("accept failed"));
223
 
    }
 
280
again:
 
281
    if (connect(p->sock, (struct sockaddr *) &p->server_addr,
 
282
                sizeof(p->server_addr)) < 0) {
 
283
#ifdef ECONNREFUSED
 
284
      if (errno == ECONNREFUSED)
 
285
        goto again;
 
286
#endif
 
287
      return csound->InitError(csound, Str("connect failed (%d)"), errno);
 
288
    }
 
289
 
224
290
    return OK;
225
291
}
226
292
 
228
294
{
229
295
    int     n = sizeof(MYFLT) * csound->ksmps;
230
296
 
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"));
233
301
    }
 
302
 
234
303
    return OK;
235
304
}
236
305
 
237
306
#define S(x)    sizeof(x)
238
307
 
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 }
246
315
};
247
316
 
248
 
LINKAGE
249
 
 
 
317
LINKAGE1(socksend_localops)