CSL  6.0
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 
AdditiveInstrument.h – Sum-of-sines synthesis instrument class.
Definition: Accessor.h:17
void nextBuffer(Buffer &outputBuffer)
Get a buffer of frames.
void * RS_read_loop(void *inst)
struct sockaddr_in mServerAddr
Socket addresses for the remote server and for me.
Definition: RemoteStream.h:127
RemoteStream class.
Definition: RemoteStream.h:100
RemoteStream(char *clientName, unsigned short clientPort, unsigned ch, unsigned bufSize)
Constructor.
sample ** ioBuffers()
Accessors used by the reader thread.
Definition: RemoteStream.h:107
unsigned bufferIndex()
Definition: RemoteStream.h:111
int initSockets(char *serverName, unsigned short serverPort)
float sample
(could be changed to int, or double)
Definition: CSL_Types.h:191
unsigned mBufferSize
the size of the input ring buffer (in FRAMES)
Definition: RemoteStream.h:119
unsigned short channels
Definition: RemoteStream.h:62
virtual int connectToServer()
unsigned short frames
Definition: RemoteStream.h:61
sample * mIoBuffers[2]
My IO buffers (2 for dbl-buffering; mBufferSize frames in size)
Definition: RemoteStream.h:120
sem_t * mServerSemaphore
Semaphore to trigger call to server for samples.
Definition: RemoteStream.h:128
sem_t * semaphore()
Definition: RemoteStream.h:113
int CSL_CreateThread(THREAD_START_ROUTINE pfnThreadProc, void *pvParam)
unsigned mCurrentBuffer
current IO buffer in use
Definition: RemoteStream.h:121
unsigned bufferSize()
Definition: RemoteStream.h:112
Buffer – the multi-channel sample buffer class (passed around between generators and IO guys)...
Definition: CSL_Core.h:106
CSL_RS_MSG mHeader
The request packet header.
Definition: RemoteStream.h:126
unsigned bufferSwitch()
Definition: RemoteStream.h:110
void *(* THREAD_START_ROUTINE)(void *)
Definition: RemoteStream.h:93
unsigned magic
Definition: RemoteStream.h:60
forward declaration
Definition: CSL_Core.h:241
unsigned mCurrentFrame
current position in buffer
Definition: RemoteStream.h:122
int mSocket
The socket I send to.
Definition: RemoteStream.h:125
unsigned short requestSize()
Definition: RemoteStream.h:109
Base class of CSL exceptions (written upper-case). Has a string message.