00001 //***************************************************************** 00002 /* 00003 JackTrip: A System for High-Quality Audio Network Performance 00004 over the Internet 00005 00006 Copyright (c) 2008 Juan-Pablo Caceres, Chris Chafe. 00007 SoundWIRE group at CCRMA, Stanford University. 00008 00009 Permission is hereby granted, free of charge, to any person 00010 obtaining a copy of this software and associated documentation 00011 files (the "Software"), to deal in the Software without 00012 restriction, including without limitation the rights to use, 00013 copy, modify, merge, publish, distribute, sublicense, and/or sell 00014 copies of the Software, and to permit persons to whom the 00015 Software is furnished to do so, subject to the following 00016 conditions: 00017 00018 The above copyright notice and this permission notice shall be 00019 included in all copies or substantial portions of the Software. 00020 00021 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 00022 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 00023 OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00024 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 00025 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 00026 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 00027 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 00028 OTHER DEALINGS IN THE SOFTWARE. 00029 */ 00030 //***************************************************************** 00031 00038 #ifndef __PACKETHEADER_H__ 00039 #define __PACKETHEADER_H__ 00040 00041 #include <iostream> 00042 #include <tr1/memory> // for shared_ptr 00043 #include <cstring> 00044 00045 #include "jacktrip_types.h" 00046 #include "jacktrip_globals.h" 00047 class JackTrip; // Forward Declaration 00048 00049 00051 struct HeaderStruct{}; 00052 00054 struct DefaultHeaderStruct : public HeaderStruct 00055 { 00056 public: 00057 // watch out for alignment... 00058 uint64_t TimeStamp; 00059 uint16_t SeqNumber; 00060 uint16_t BufferSize; 00061 uint8_t SamplingRate; 00062 uint8_t BitResolution; 00063 uint8_t NumInChannels; 00064 uint8_t NumOutChannels; 00065 //uint8_t Dummy; ///< Dummy value to byte padding alignment 00066 }; 00067 00068 //--------------------------------------------------------- 00069 //JamLink UDP Header: 00070 /************************************************************************/ 00071 /* values for the UDP stream type */ 00072 /* streamType is a 16-bit value at the head of each UDP stream */ 00073 /* Its bit map is as follows: (b15-msb) */ 00074 /* B15:reserved, B14:extended header, B13 Stereo, B12 not 16-bit */ 00075 /* B11-B9: 0-48 Khz, 1-44 Khz, 2-32 Khz, 3-24 Khz, */ 00076 /* 4-22 Khz, 5-16 Khz, 6-11 Khz, 7-8 Khz */ 00077 /* B8-0: Samples in packet */ 00078 /************************************************************************/ 00079 const unsigned short ETX_RSVD = (0<<15); 00080 const unsigned short ETX_XTND = (1<<14); 00081 const unsigned short ETX_STEREO = (1<<13); 00082 const unsigned short ETX_MONO = (0<<13); 00083 const unsigned short ETX_16BIT = (0<<12); 00084 //inline unsigned short ETX_RATE_MASK(const unsigned short a) { a&(0x7<<9); } 00085 const unsigned short ETX_48KHZ = (0<<9); 00086 const unsigned short ETX_44KHZ = (1<<9); 00087 const unsigned short ETX_32KHZ = (2<<9); 00088 const unsigned short ETX_24KHZ = (3<<9); 00089 const unsigned short ETX_22KHZ = (4<<9); 00090 const unsigned short ETX_16KHZ = (5<<9); 00091 const unsigned short ETX_11KHZ = (6<<9); 00092 const unsigned short ETX_8KHZ = (7<<9); 00093 // able to express up to 512 SPP 00094 //inline unsigned short ETX_SPP(const unsigned short a) { (a&0x01FF); } 00095 00097 struct JamLinkHeaderStuct : public HeaderStruct 00098 { 00099 // watch out for alignment -- need to be on 4 byte chunks 00100 uint16_t Common; 00101 uint16_t SeqNumber; 00102 uint32_t TimeStamp; 00103 }; 00104 00105 00106 //####################################################################### 00107 //####################### PacketHeader ################################## 00108 //####################################################################### 00112 class PacketHeader 00113 { 00114 public: 00116 PacketHeader(JackTrip* jacktrip); 00118 virtual ~PacketHeader() {}; 00119 00123 static uint64_t usecTime(); 00124 00127 virtual void fillHeaderCommonFromAudio() = 0; 00128 00129 /* \brief Parse the packet header and take appropriate measures (like change settings, or 00130 * quit the program if peer settings don't match) 00131 */ 00132 virtual void parseHeader() = 0; 00133 00134 virtual void checkPeerSettings(int8_t* full_packet) = 0; 00135 virtual uint16_t getPeerSequenceNumber(int8_t* full_packet) const = 0; 00136 00137 /* \brief Increase sequence number for counter, a 16bit number 00138 */ 00139 virtual void increaseSequenceNumber() 00140 { 00141 mSeqNumber++; 00142 }; 00143 00144 /* \brief Returns the current sequence number 00145 * \return 16bit Sequence number 00146 */ 00147 virtual uint16_t getSequenceNumber() const 00148 { 00149 return mSeqNumber; 00150 } 00151 00152 /* \brief Get the header size in bytes 00153 */ 00154 virtual int getHeaderSizeInBytes() const = 0; 00155 00156 00157 virtual void putHeaderInPacketBaseClass(int8_t* full_packet, 00158 const HeaderStruct& header_struct) 00159 { 00160 std::memcpy(full_packet, reinterpret_cast<const void*>(&header_struct), 00161 getHeaderSizeInBytes() ); 00162 }; 00163 00164 /* \brief Put the header in buffer pointed by full_packet 00165 * \param full_packet Pointer to full packet (audio+header). Size must be 00166 * sizeof(header part) + sizeof(audio part) 00167 */ 00168 virtual void putHeaderInPacket(int8_t* full_packet) = 0; 00169 00170 private: 00171 uint16_t mSeqNumber; 00172 JackTrip* mJackTrip; 00173 }; 00174 00175 00176 00177 00178 //####################################################################### 00179 //####################### DefaultHeader ################################# 00180 //####################################################################### 00183 class DefaultHeader : public PacketHeader 00184 { 00185 public: 00186 /* 00187 //----------STRUCT----------------------------------------- 00189 struct DefaultHeaderStruct 00190 { 00191 // watch out for alignment... 00192 uint64_t TimeStamp; ///< Time Stamp 00193 uint16_t SeqNumber; ///< Sequence Number 00194 uint16_t BufferSize; ///< Buffer Size in Samples 00195 uint8_t SamplingRate; ///< Sampling Rate in JackAudioInterface::samplingRateT 00196 uint8_t NumInChannels; ///< Number of Input Channels 00197 uint8_t NumOutChannels; ///< Number of Output Channels 00198 // uint8_t BitResolution; ///< \todo implement this part 00199 }; 00200 //--------------------------------------------------------- 00201 */ 00202 DefaultHeader(JackTrip* jacktrip); 00203 virtual ~DefaultHeader() {}; 00204 virtual void fillHeaderCommonFromAudio(); 00205 virtual void parseHeader() {}; 00206 virtual void checkPeerSettings(int8_t* full_packet); 00207 virtual void increaseSequenceNumber() 00208 { 00209 mHeader.SeqNumber++; 00210 //std::cout << "Sequence Number = " << static_cast<int>(mHeader.SeqNumber) << std::endl; 00211 }; 00212 virtual uint16_t getSequenceNumber() const 00213 { 00214 return mHeader.SeqNumber; 00215 } 00216 virtual uint16_t getPeerSequenceNumber(int8_t* full_packet) const; 00217 virtual int getHeaderSizeInBytes() const { return sizeof(mHeader); }; 00218 virtual void putHeaderInPacket(int8_t* full_packet) 00219 { 00220 putHeaderInPacketBaseClass(full_packet, mHeader); 00221 //std::memcpy(full_packet, reinterpret_cast<const void*>(&mHeader), 00222 // getHeaderSizeInBytes() ); 00223 }; 00224 void printHeader() const; 00225 00226 private: 00227 //DefaultHeaderStruct mHeader; ///< Header Struct 00228 DefaultHeaderStruct mHeader; 00229 JackTrip* mJackTrip; 00230 }; 00231 00232 00233 00234 00235 //####################################################################### 00236 //####################### JamLinkHeader ################################# 00237 //####################################################################### 00238 00241 class JamLinkHeader : public PacketHeader 00242 { 00243 public: 00244 00245 JamLinkHeader(JackTrip* jacktrip); 00246 virtual ~JamLinkHeader() {}; 00247 00248 virtual void fillHeaderCommonFromAudio(); 00249 virtual void parseHeader() {}; 00250 virtual void checkPeerSettings(int8_t* /*full_packet*/) {} 00251 virtual uint16_t getPeerSequenceNumber(int8_t* /*full_packet*/) const { /*\todo IMPLEMENT*/ return 0; } 00252 virtual void increaseSequenceNumber() {}; 00253 virtual int getHeaderSizeInBytes() const { return sizeof(mHeader); }; 00254 virtual void putHeaderInPacket(int8_t* full_packet) 00255 { 00256 putHeaderInPacketBaseClass(full_packet, mHeader); 00257 }; 00258 00259 private: 00260 JamLinkHeaderStuct mHeader; 00261 JackTrip* mJackTrip; 00262 }; 00263 00264 00265 00266 //####################################################################### 00267 //####################### EmptyHeader ################################# 00268 //####################################################################### 00269 00272 class EmptyHeader : public PacketHeader 00273 { 00274 public: 00275 00276 EmptyHeader(JackTrip* jacktrip); 00277 virtual ~EmptyHeader() {}; 00278 00279 virtual void fillHeaderCommonFromAudio() {}; 00280 virtual void parseHeader() {}; 00281 virtual void checkPeerSettings(int8_t* /*full_packet*/) {} 00282 virtual uint16_t getPeerSequenceNumber(int8_t* /*full_packet*/) const { return 0; /*\todo IMPLEMENT*/} 00283 virtual void increaseSequenceNumber() {}; 00284 virtual int getHeaderSizeInBytes() const { return 0; }; 00285 virtual void putHeaderInPacket(int8_t* /*full_packet*/) {}; 00286 00287 private: 00288 JackTrip* mJackTrip; 00289 }; 00290 00291 00292 #endif //__PACKETHEADER_H__