RemoteStream.h

Go to the documentation of this file.
00001 //
00002 //  RemoteStream.h -- a frame stream that sends network requests to a server to get buffers.
00003 //  See the copyright notice and acknowledgment of authors in the file COPYRIGHT
00004 //
00005 // The server is assumed to be on a remote machine, and is a CSL program that uses a RemoteIO
00006 // port for output. The request packet sent to the server from this client causes it to call 
00007 // its DSP graph's next_buffer() method and return the sample buffer via the TCP-IP socket.
00008 //
00009 // The request packet format is given in the structure CSL_RFS_MSG.
00010 // The response packet format starts with the same header, followed by raw sample data as 
00011 // non-interleaved floats, followed by the magic number as a packet footer.
00012 //
00013 // To set this up, the server must be a CSL program, and the RemoteIO object must know what port it 
00014 // it listens to. The client (this RemoteStream) needs to know the server's hostname and port.
00015 // The client first sends the server an "introduction" packet so that the server can open a
00016 // response socket. Then the client can send the server sample buffer requests.
00017 //
00018 // Note that the RemoteStream's packet size will typically be larger than the buffer size of the 
00019 // client's DSP graph. In the tests, we use a packet size of 8000 samples and a client block size
00020 // of 500.
00021 //
00022 
00023 #ifndef CSL_RemoteStream_H
00024 #define CSL_RemoteStream_H
00025 
00026 #include "CSL_Includes.h"
00027 #include "ThreadUtilities.h"
00028 
00029 #include <stdio.h>
00030 #include <stdlib.h>
00031 #include <semaphore.h>
00032 
00033 #ifdef CSL_WINDOWS      // MS-Windows socket includes
00034 
00035 #include <winsock.h>
00036 typedef unsigned int in_addr_t;
00037 typedef int ssize_t;
00038 #define MAXHOSTNAMELEN 256
00039 #include <fcntl.h>
00040 #define SEM_FAILED ((sem_t*) 0) // For pthread semaphores -- why do we need this?
00041 
00042 #else                   // UNIX socket includes
00043 
00044 #include <unistd.h>
00045 #include <sys/types.h>
00046 #include <sys/socket.h>
00047 #include <sys/param.h>
00048 #include <netdb.h>
00049 #include <netinet/in.h>
00050 #include <arpa/inet.h>
00051 #define closesocket(x)  ::close(x)
00052 
00053 #endif
00054 
00055 namespace csl {
00056 
00057 // CSL RS protocol message header structure (8 bytes)
00058 
00059 typedef struct {
00060     unsigned magic;             // Magic number (=0x004200XX, whereby XX is the command)
00061     unsigned short frames;      // Number of frames requested
00062     unsigned short channels;        // Number of channels requested
00063 } CSL_RS_MSG;
00064 
00065 // Useful macros for managing packet I/O
00066 
00067 #define RS_PACKET_MAGIC 0x00420000                      // RS packet magic number
00068 #define RS_PACKET_SIZE (sizeof(CSL_RFS_MSG))            // Size of RS request packets
00069 #define RS_BUFFER_SIZE (mBufferSize * mNumChannels * sizeof(sample))
00070 #define RS_RESPONSE_PACKET_SIZE (RFS_PACKET_SIZE + RS_BUFFER_SIZE + 4)
00071 
00072 // Default I/O port (ought to use PortMapper to pass port #s as cmd-line options)
00073 
00074 #define CSL_DEFAULT_REQUEST_PORT 57574  // Default port for RS requests (server listener)
00075 
00076 //#define RS_TIMING                 // Print out the timing code
00077 
00078 // Remote commands
00079 
00080 #define CSL_CMD_SET_CLIENT      42      // Set up the server's response socket to the client
00081 #define CSL_CMD_NEXT_BUFFER     43      // Request a buffer of samples from the server
00082 //#define CSL_CMD_NEXT_SAMPLE   44      // Request a single sample from the server
00083 //#define CSL_CMD_GET_RATE      45      // Query the server's sample rate
00084 //#define CSL_CMD_GET_CHANNELS  46      // Query the server's # of channels
00085 #define CSL_CMD_STOP            47      // Stop the server
00086 
00087 // The RS read loop; this is spawned as a separate thread
00088 
00089 extern "C" void * RS_read_loop(void * inst);
00090 
00091 // Thread utilities
00092 
00093 typedef void * (*THREAD_START_ROUTINE)(void *);
00094 extern "C" int CSL_CreateThread(THREAD_START_ROUTINE pfnThreadProc, void * pvParam);
00095 
00099 
00100 class RemoteStream : public UnitGenerator {
00101 
00102 public:                 
00103     RemoteStream(char * clientName, unsigned short clientPort, unsigned ch, unsigned bufSize);
00104     ~RemoteStream();
00105 
00107     sample **ioBuffers() { return mIoBuffers; };
00108     int socket() { return mSocket; };
00109     unsigned short requestSize() { return (RFS_BUFFER_SIZE); };
00110     unsigned bufferSwitch() { return mCurrentBuffer; };
00111     unsigned bufferIndex() { return mCurrentFrame; };
00112     unsigned bufferSize() { return mBufferSize; };
00113     sem_t *semaphore() { return mServerSemaphore; };
00114     
00116     void nextBuffer(Buffer &outputBuffer) throw(CException);
00117 
00118 protected:              // Basic data
00119     unsigned mBufferSize;               
00120     sample * mIoBuffers[2];             
00121     unsigned mCurrentBuffer;            
00122     unsigned mCurrentFrame;             
00123     
00124                         // Socket-related members
00125     int mSocket;                        
00126     CSL_RS_MSG mHeader;             
00127     struct sockaddr_in mServerAddr;     
00128     sem_t * mServerSemaphore;           
00129     
00130                         // Protected low-level setup methods
00131     int initSockets(char * serverName, unsigned short serverPort);
00132     void initPacket();
00133     virtual int connectToServer();
00134 
00135 };
00136 
00137 }
00138 
00139 #endif
00140 

Generated on Thu Sep 17 23:14:15 2009 for CSL by  doxygen 1.5.8