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 virtual uint64_t getPeerTimeStamp(int8_t* full_packet) const = 0; 00137 00138 00139 /* \brief Increase sequence number for counter, a 16bit number 00140 */ 00141 virtual void increaseSequenceNumber() 00142 { 00143 mSeqNumber++; 00144 }; 00145 00146 /* \brief Returns the current sequence number 00147 * \return 16bit Sequence number 00148 */ 00149 virtual uint16_t getSequenceNumber() const 00150 { 00151 return mSeqNumber; 00152 } 00153 00154 /* \brief Get the header size in bytes 00155 */ 00156 virtual int getHeaderSizeInBytes() const = 0; 00157 00158 00159 virtual void putHeaderInPacketBaseClass(int8_t* full_packet, 00160 const HeaderStruct& header_struct) 00161 { 00162 std::memcpy(full_packet, reinterpret_cast<const void*>(&header_struct), 00163 getHeaderSizeInBytes() ); 00164 }; 00165 00166 /* \brief Put the header in buffer pointed by full_packet 00167 * \param full_packet Pointer to full packet (audio+header). Size must be 00168 * sizeof(header part) + sizeof(audio part) 00169 */ 00170 virtual void putHeaderInPacket(int8_t* full_packet) = 0; 00171 00172 private: 00173 uint16_t mSeqNumber; 00174 JackTrip* mJackTrip; 00175 }; 00176 00177 00178 00179 00180 //####################################################################### 00181 //####################### DefaultHeader ################################# 00182 //####################################################################### 00185 class DefaultHeader : public PacketHeader 00186 { 00187 public: 00188 00189 DefaultHeader(JackTrip* jacktrip); 00190 virtual ~DefaultHeader() {} 00191 00192 virtual void fillHeaderCommonFromAudio(); 00193 virtual void parseHeader() {} 00194 virtual void checkPeerSettings(int8_t* full_packet); 00195 virtual void increaseSequenceNumber() 00196 { 00197 mHeader.SeqNumber++; 00198 //std::cout << "Sequence Number = " << static_cast<int>(mHeader.SeqNumber) << std::endl; 00199 } 00200 virtual uint16_t getSequenceNumber() const 00201 { 00202 return mHeader.SeqNumber; 00203 } 00204 virtual uint16_t getPeerSequenceNumber(int8_t* full_packet) const; 00205 virtual uint64_t getPeerTimeStamp(int8_t* /*full_packet*/) const 00206 { return 0; } 00207 virtual int getHeaderSizeInBytes() const { return sizeof(mHeader); } 00208 virtual void putHeaderInPacket(int8_t* full_packet) 00209 { 00210 putHeaderInPacketBaseClass(full_packet, mHeader); 00211 //std::memcpy(full_packet, reinterpret_cast<const void*>(&mHeader), 00212 // getHeaderSizeInBytes() ); 00213 } 00214 void printHeader() const; 00215 00216 private: 00217 //DefaultHeaderStruct mHeader; ///< Header Struct 00218 DefaultHeaderStruct mHeader; 00219 JackTrip* mJackTrip; 00220 }; 00221 00222 00223 00224 00225 //####################################################################### 00226 //####################### JamLinkHeader ################################# 00227 //####################################################################### 00228 00231 class JamLinkHeader : public PacketHeader 00232 { 00233 public: 00234 00235 JamLinkHeader(JackTrip* jacktrip); 00236 virtual ~JamLinkHeader() {} 00237 00238 virtual void fillHeaderCommonFromAudio(); 00239 virtual void parseHeader() {} 00240 virtual void checkPeerSettings(int8_t* /*full_packet*/) {} 00241 virtual uint16_t getPeerSequenceNumber(int8_t* /*full_packet*/) const 00242 { return 0; } 00243 virtual uint64_t getPeerTimeStamp(int8_t* /*full_packet*/) const 00244 { return 0; } 00245 virtual void increaseSequenceNumber() {} 00246 virtual int getHeaderSizeInBytes() const { return sizeof(mHeader); } 00247 virtual void putHeaderInPacket(int8_t* full_packet) 00248 { 00249 putHeaderInPacketBaseClass(full_packet, mHeader); 00250 }; 00251 00252 private: 00253 JamLinkHeaderStuct mHeader; 00254 JackTrip* mJackTrip; 00255 }; 00256 00257 00258 00259 //####################################################################### 00260 //####################### EmptyHeader ################################# 00261 //####################################################################### 00262 00265 class EmptyHeader : public PacketHeader 00266 { 00267 public: 00268 00269 EmptyHeader(JackTrip* jacktrip); 00270 virtual ~EmptyHeader() {} 00271 00272 virtual void fillHeaderCommonFromAudio() {} 00273 virtual void parseHeader() {} 00274 virtual void checkPeerSettings(int8_t* /*full_packet*/) {} 00275 virtual uint16_t getPeerSequenceNumber(int8_t* /*full_packet*/) const 00276 { return 0; } 00277 virtual uint64_t getPeerTimeStamp(int8_t* /*full_packet*/) const 00278 { return 0; } 00279 virtual void increaseSequenceNumber() {} 00280 virtual int getHeaderSizeInBytes() const { return 0; } 00281 virtual void putHeaderInPacket(int8_t* /*full_packet*/) {} 00282 00283 private: 00284 JackTrip* mJackTrip; 00285 }; 00286 00287 00288 #endif //__PACKETHEADER_H__