OSC-receive.h

Go to the documentation of this file.
00001 /*
00002 Copyright  1998. The Regents of the University of California (Regents). 
00003 All Rights Reserved.
00004 
00005 Written by Matt Wright, The Center for New Music and Audio Technologies,
00006 University of California, Berkeley.
00007 
00008 Permission to use, copy, modify, distribute, and distribute modified versions
00009 of this software and its documentation without fee and without a signed
00010 licensing agreement, is hereby granted, provided that the above copyright
00011 notice, this paragraph and the following two paragraphs appear in all copies,
00012 modifications, and distributions.
00013 
00014 IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
00015 SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
00016 OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
00017 BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00018 
00019 REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
00020 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00021 PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
00022 HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
00023 MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
00024 
00025 The OpenSound Control WWW page is 
00026     http://www.cnmat.berkeley.edu/OpenSoundControl
00027 */
00028 
00029 
00030 
00031 /*
00032   OSC-receive.h
00033   Matt Wright, 11/18/97
00034 
00035   include OSC-timetag.h and NetworkReturnAddress.h before this file.
00036 */
00037 
00038 
00039 /**************************************************
00040    Initialization and memory pre-allocation
00041  **************************************************/
00042 
00043 /* The memory model used by this module is pre-allocation of fixed-size
00044   objects for network buffers and other internal objects.  This preallocated
00045   memory is dynamically managed internally by a custom high-performance memory
00046   allocator.  When the preallocated memory runs out, this module calls an
00047   optional realtime memory allocator that you provide.  If your memory
00048   allocator gives this module more memory, it will add it to the pool of
00049   objects and never free the memory.  If your system does not have a realtime
00050   memory allocator, provide a procedure that always returns 0.
00051 
00052   You will fill an OSCReceiveMemoryTuner struct with the parameters that
00053   determine how memory will be allocated.
00054 
00055   The MemoryAllocator fields are procedures you will provide that allocate
00056   memory.  Like malloc(), they take the number of bytes as arguments and return
00057   either a pointer to the new memory or 0 for failure.  This memory will never
00058   be freed.
00059 
00060 - The InitTimeMemoryAllocator will be called only at initialization time,
00061   i.e., before OSCInitAddressSpace() returns.  If it ever returns 0, that's
00062   a fatal error.
00063 
00064 - The RealTimeMemoryAllocator will be called if, while the application is
00065   running, the address space grows larger than can fit in what was allocated
00066   at initialization time.  If the RealTimeMemoryAllocator() returns 0, the
00067   operation attempting to grow the address space will fail.  If your system
00068   does not have real-time memory allocation, RealTimeMemoryAllocator should
00069   be a procedure that always returns 0.
00070 
00071   The remaining fields say how much memory to allocate at initialization time:
00072 
00073 - receiveBufferSize is the maximum packet size that can be received.  Is the
00074   maximum UDP packet size 4096?  OSC clients can send a query to this system 
00075   asking for this maximum packet size.
00076 
00077 - numReceiveBuffers determines how many packets at a time can be sitting
00078   on the scheduler with messages waiting to take effect.  If all the 
00079   receive buffers are tied up like this, you won't be able to receive
00080   new packets.
00081 
00082 - numQueuedObjects is the number of messages and packets that can be sitting
00083   on the scheduler waiting to take effect.
00084 
00085 - Because a message pattern may be dispatched before the message takes effect,
00086   we need memory to store the callback pointers corresponding to a message.
00087   numCallbackListNodes is the number of callbacks that may be stored in this
00088   fashion.  It must be at least as large as the maximum number of methods that
00089   any one message pattern may match, but if you want to take advantage of
00090   pre-dispatching, this should be large enough to hold all the callbacks for
00091   all the messages waiting in the scheduler.
00092 
00093 */
00094 
00095 
00096 struct OSCReceiveMemoryTuner {
00097     void *(*InitTimeMemoryAllocator)(int numBytes);
00098     void *(*RealTimeMemoryAllocator)(int numBytes);
00099     int receiveBufferSize;
00100     int numReceiveBuffers;
00101     int numQueuedObjects;
00102     int numCallbackListNodes;
00103 };
00104 
00105 /* Given an OSCReceiveMemoryTuner, return the number of bytes of
00106    memory that would be allocated if OSCInitReceive() were called
00107    on it. */
00108 int OSCReceiveMemoryThatWouldBeAllocated(struct OSCReceiveMemoryTuner *t);
00109 
00110 /* Returns FALSE if it fails to initialize */
00111 Boolean OSCInitReceive(struct OSCReceiveMemoryTuner *t);
00112 
00113 /**************************************************
00114    Managing packet data structures
00115  **************************************************/
00116 
00117 
00118 /* You don't get to know what's in an OSCPacketBuffer. */
00119 typedef struct OSCPacketBuffer_struct *OSCPacketBuffer;
00120 
00121 /* Get an unused packet.  Returns 0 if none are free.  If you get a packet
00122    with this procedure, it is your responsibility either to call
00123    OSCAcceptPacket() on it (in which case the internals of the OSC Kit free
00124    the OSCPacketBuffer after the last message in it takes effect) or to call
00125    OSCFreePacket() on it. */
00126 OSCPacketBuffer OSCAllocPacketBuffer(void);
00127 
00128 /* Free.  This is called automatically after the last message that was
00129    in the packet is invoked.  You shouldn't need to call this unless
00130    you get a packet with OSCAllocPacketBuffer() and then for some reason
00131    decide not to call OSCAcceptPacket() on it. */
00132 void OSCFreePacket(OSCPacketBuffer p);
00133 
00134 /* Whatever code actually gets packets from the network should use these
00135    three selectors to access the fields in the packet structure that need
00136    to be filled in with the data from the network. */
00137 
00138 /* Selector to get the buffer from a packet.  This buffer's size will be
00139    equal to the receiveBufferSize you passed to OSCInitReceive(). */
00140 char *OSCPacketBufferGetBuffer(OSCPacketBuffer p);
00141 
00142 /* Selector to get a pointer to the int that's the size count for the
00143    data currently in a packet.  (Not the capacity of the packet's buffer,
00144    but the size of the packet that's actually stored in the buffer.) */
00145 int *OSCPacketBufferGetSize(OSCPacketBuffer);
00146 
00147 /* Selector to get the client's network address from a packet.  This buffer's
00148    size will be equal to the clientAddrSize you passed to OSCInitReceive(). 
00149    Note that the NetworkReturnAddressPtr type is full of "const"s, so your
00150    code that fills in the return address will probably have to cast the return
00151    value of this procedure to some non-const type to be able to write into it. */
00152 NetworkReturnAddressPtr OSCPacketBufferGetClientAddr(OSCPacketBuffer p);
00153 
00154 /* Returns the capacity of packet buffers (the receiveBufferSize you passed
00155    to OSCInitReceive()). */
00156 int OSCGetReceiveBufferSize(void);
00157 
00158 
00159 /**************************************************
00160    Dealing with OpenSoundControl packets and
00161    making the messages take effect.
00162  **************************************************/
00163 
00164 /* Call this as soon as a packet comes in from the network.
00165    It will take care of anything that has to happen immediately,
00166    but put off as much as possible of the work of parsing the
00167    packet.  (This tries to be as fast as possible in case a 
00168    lot of packets come in.) */
00169 void OSCAcceptPacket(OSCPacketBuffer packet);
00170 
00171 /* Call this during an otherwise idle time.  It goes through
00172    everything that's sitting in the OSC scheduler waiting to
00173    happen and does some of the work of parsing, pattern
00174    matching, dispatching, etc., that will have to be done
00175    at some point before the scheduled messages can take
00176    effect.
00177 
00178    The return value indicates whether there is more work of
00179    this sort that could be done.  (Each time you call this,
00180    it does only a small unit of this kind of work.  If it
00181    returns TRUE and you still have time before the next thing
00182    you have to do, call it again.) */
00183 Boolean OSCBeProductiveWhileWaiting(void);
00184 
00185 /* Call this whenever enough time has passed that you want to see which
00186    messages are now ready and have them take effect.  (For example, in a
00187    synthesizer, you might call this once per synthesis frame, just before
00188    synthesizing the audio for that frame.)
00189 
00190    This procedure finds the earliest time tag of all the queued messages
00191    and invokes *all* of the queued messages with that time tag.  (OSC
00192    guarantees that messages with the same tag take effect atomically.)
00193    If there are more messages that are ready, but with a different time
00194    tag, this procedure does not invoke them, but returns TRUE to indicate
00195    that more messages are ready.
00196 */
00197 Boolean OSCInvokeMessagesThatAreReady(OSCTimeTag now);
00198 
00199 /* Same thing, but invokes all of the messages whose time has come. */
00200 void OSCInvokeAllMessagesThatAreReady(OSCTimeTag now);
00201 
00202 
00203 
00204 /**************************************************
00205    How to use this stuff
00206  **************************************************/
00207 
00208 /* Here's a gross approximation of how your application will invoke the
00209    procedures in this module:
00210 
00211 while (1) {
00212     OSCTimeTag now = CurrentTime();
00213     do {
00214     if (WeAreSoLateThatWeNeedToDelayOSCMessagesToAvoidACrisis()) break;
00215     } while (OSCInvokeMessagesThatAreReady(now) == TRUE);
00216 
00217     SynthesizeSomeSound();
00218     if (NetworkPacketWaiting()) {
00219     OSCPacketBuffer p = OSCAllocPacketBuffer();
00220     if (!p) {
00221         Bummer();
00222     } else {
00223         NetworkReceivePacket(p);
00224         OSCAcceptPacket(p);
00225     }
00226     }
00227     while (TimeLeftBeforeWeHaveDoSomething()) {
00228     if (!OSCBeProductiveWhileWaiting()) break;
00229     }
00230 }
00231 
00232 */
00233 

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