CSL 5.2

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

RemoteStream.h
Go to the documentation of this file.
1 //
2 // RemoteStream.h -- a frame stream that sends network requests to a server to get buffers.
3 // See the copyright notice and acknowledgment of authors in the file COPYRIGHT
4 //
5 // The server is assumed to be on a remote machine, and is a CSL program that uses a RemoteIO
6 // port for output. The request packet sent to the server from this client causes it to call
7 // its DSP graph's next_buffer() method and return the sample buffer via the TCP-IP socket.
8 //
9 // The request packet format is given in the structure CSL_RFS_MSG.
10 // The response packet format starts with the same header, followed by raw sample data as
11 // non-interleaved floats, followed by the magic number as a packet footer.
12 //
13 // To set this up, the server must be a CSL program, and the RemoteIO object must know what port it
14 // it listens to. The client (this RemoteStream) needs to know the server's hostname and port.
15 // The client first sends the server an "introduction" packet so that the server can open a
16 // response socket. Then the client can send the server sample buffer requests.
17 //
18 // Note that the RemoteStream's packet size will typically be larger than the buffer size of the
19 // client's DSP graph. In the tests, we use a packet size of 8000 samples and a client block size
20 // of 500.
21 //
22
23 #ifndef CSL_RemoteStream_H
24 #define CSL_RemoteStream_H
25
26 #include "CSL_Includes.h"
27 #include "ThreadUtilities.h"
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <semaphore.h>
32
33 #ifdef CSL_WINDOWS // MS-Windows socket includes
34
35 #include <winsock.h>
36 typedef unsigned int in_addr_t;
37 typedef int ssize_t;
38 #define MAXHOSTNAMELEN 256
39 #include <fcntl.h>
40 #define SEM_FAILED ((sem_t*) 0) // For pthread semaphores -- why do we need this?
41
42 #else // UNIX socket includes
43
44 #include <unistd.h>
45 #include <sys/types.h>
46 #include <sys/socket.h>
47 #include <sys/param.h>
48 #include <netdb.h>
49 #include <netinet/in.h>
50 #include <arpa/inet.h>
51 #define closesocket(x) ::close(x)
52
53 #endif
54
55 namespace csl {
56
57 // CSL RS protocol message header structure (8 bytes)
58
59 typedef struct {
60 unsigned magic; // Magic number (=0x004200XX, whereby XX is the command)
61 unsigned short frames; // Number of frames requested
62 unsigned short channels; // Number of channels requested
63 } CSL_RS_MSG;
64
65 // Useful macros for managing packet I/O
66
67 #define RS_PACKET_MAGIC 0x00420000 // RS packet magic number
68 #define RS_PACKET_SIZE (sizeof(CSL_RFS_MSG)) // Size of RS request packets
69 #define RS_BUFFER_SIZE (mBufferSize * mNumChannels * sizeof(sample))
70 #define RS_RESPONSE_PACKET_SIZE (RFS_PACKET_SIZE + RS_BUFFER_SIZE + 4)
71
72 // Default I/O port (ought to use PortMapper to pass port #s as cmd-line options)
73
74 #define CSL_DEFAULT_REQUEST_PORT 57574 // Default port for RS requests (server listener)
75
76 //#define RS_TIMING // Print out the timing code
77
78 // Remote commands
79
80 #define CSL_CMD_SET_CLIENT 42 // Set up the server's response socket to the client
81 #define CSL_CMD_NEXT_BUFFER 43 // Request a buffer of samples from the server
82 //#define CSL_CMD_NEXT_SAMPLE 44 // Request a single sample from the server
83 //#define CSL_CMD_GET_RATE 45 // Query the server's sample rate
84 //#define CSL_CMD_GET_CHANNELS 46 // Query the server's # of channels
85 #define CSL_CMD_STOP 47 // Stop the server
86
87 // The RS read loop; this is spawned as a separate thread
88
89 extern "C" void * RS_read_loop(void * inst);
90
91 // Thread utilities
92
93 typedef void * (*THREAD_START_ROUTINE)(void *);
94 extern "C" int CSL_CreateThread(THREAD_START_ROUTINE pfnThreadProc, void * pvParam);
95
96 ///
97 /// RemoteStream class
98 ///
99
100 class RemoteStream : public UnitGenerator {
101
102 public: /// Constructor
103 RemoteStream(char * clientName, unsigned short clientPort, unsigned ch, unsigned bufSize);
104 ~RemoteStream();
105
106 /// Accessors used by the reader thread
107 sample **ioBuffers() { return mIoBuffers; };
108 int socket() { return mSocket; };
109 unsigned short requestSize() { return (RFS_BUFFER_SIZE); };
110 unsigned bufferSwitch() { return mCurrentBuffer; };
111 unsigned bufferIndex() { return mCurrentFrame; };
112 unsigned bufferSize() { return mBufferSize; };
113 sem_t *semaphore() { return mServerSemaphore; };
114
115 /// Get a buffer of frames
116 void nextBuffer(Buffer &outputBuffer) throw(CException);
117
118 protected: // Basic data
119 unsigned mBufferSize; ///< the size of the input ring buffer (in FRAMES)
120 sample * mIoBuffers[2]; ///< My IO buffers (2 for dbl-buffering; mBufferSize frames in size)
121 unsigned mCurrentBuffer; ///< current IO buffer in use
122 unsigned mCurrentFrame; ///< current position in buffer
123
124 // Socket-related members
125 int mSocket; ///< The socket I send to
126 CSL_RS_MSG mHeader; ///< The request packet header
127 struct sockaddr_in mServerAddr; ///< Socket addresses for the remote server and for me
128 sem_t * mServerSemaphore; ///< Semaphore to trigger call to server for samples
129
130 // Protected low-level setup methods
131 int initSockets(char * serverName, unsigned short serverPort);
132 void initPacket();
133 virtual int connectToServer();
134
135 };
136
137 }
138
139 #endif
140