1 //***************************************************************** 2 /* 3 JackTrip: A System for High-Quality Audio Network Performance 4 over the Internet 5 6 Copyright (c) 2008 Juan-Pablo Caceres, Chris Chafe. 7 SoundWIRE group at CCRMA, Stanford University. 8 9 Permission is hereby granted, free of charge, to any person 10 obtaining a copy of this software and associated documentation 11 files (the "Software"), to deal in the Software without 12 restriction, including without limitation the rights to use, 13 copy, modify, merge, publish, distribute, sublicense, and/or sell 14 copies of the Software, and to permit persons to whom the 15 Software is furnished to do so, subject to the following 16 conditions: 17 18 The above copyright notice and this permission notice shall be 19 included in all copies or substantial portions of the Software. 20 21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 23 OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 25 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 26 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 27 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 28 OTHER DEALINGS IN THE SOFTWARE. 29 */ 30 //***************************************************************** 31 32 /** 33 * \file PacketHeader.h 34 * \author Juan-Pablo Caceres 35 * \date July 2008 36 */ 37 38 #ifndef __PACKETHEADER_H__ 39 #define __PACKETHEADER_H__ 40 41 #include <iostream> 42 //#include <tr1/memory> // for shared_ptr 43 #include <cstring> 44 45 #include <QObject> 46 #include <QString> 47 48 #include "jacktrip_types.h" 49 #include "jacktrip_globals.h" 50 class JackTrip; // Forward Declaration 51 52 53 /// \brief Abstract Header Struct, Header Stucts should subclass it 54 struct HeaderStruct{}; 55 56 /// \brief Default Header Struct 57 struct DefaultHeaderStruct : public HeaderStruct 58 { 59 public: 60 // watch out for alignment... 61 uint64_t TimeStamp; ///< Time Stamp 62 uint16_t SeqNumber; ///< Sequence Number 63 uint16_t BufferSize; ///< Buffer Size in Samples 64 uint8_t SamplingRate; ///< Sampling Rate in JackAudioInterface::samplingRateT 65 uint8_t BitResolution; ///< Audio Bit Resolution 66 //uint8_t NumInChannels; ///< Number of Input Channels 67 //uint8_t NumOutChannels; ///< Number of Output Channels 68 uint8_t NumChannels; ///< Number of Channels, we assume input and outputs are the same 69 uint8_t ConnectionMode; 70 }; 71 72 //--------------------------------------------------------- 73 //JamLink UDP Header: 74 /************************************************************************/ 75 /* values for the UDP stream type */ 76 /* streamType is a 16-bit value at the head of each UDP stream */ 77 /* Its bit map is as follows: (b15-msb) */ 78 /* B15:reserved, B14:extended header, B13 Stereo, B12 not 16-bit */ 79 /* B11-B9: 0-48 Khz, 1-44 Khz, 2-32 Khz, 3-24 Khz, */ 80 /* 4-22 Khz, 5-16 Khz, 6-11 Khz, 7-8 Khz */ 81 /* B8-0: Samples in packet */ 82 /************************************************************************/ 83 const unsigned short ETX_RSVD = (0<<15); 84 const unsigned short ETX_XTND = (1<<14); 85 const unsigned short ETX_STEREO = (1<<13); 86 const unsigned short ETX_MONO = (0<<13); 87 const unsigned short ETX_16BIT = (0<<12); 88 //inline unsigned short ETX_RATE_MASK(const unsigned short a) { a&(0x7<<9); } 89 const unsigned short ETX_48KHZ = (0<<9); 90 const unsigned short ETX_44KHZ = (1<<9); 91 const unsigned short ETX_32KHZ = (2<<9); 92 const unsigned short ETX_24KHZ = (3<<9); 93 const unsigned short ETX_22KHZ = (4<<9); 94 const unsigned short ETX_16KHZ = (5<<9); 95 const unsigned short ETX_11KHZ = (6<<9); 96 const unsigned short ETX_8KHZ = (7<<9); 97 // able to express up to 512 SPP 98 //inline unsigned short ETX_SPP(const unsigned short a) { (a&0x01FF); } 99 100 /// \brief JamLink Header Struct 101 struct JamLinkHeaderStuct : public HeaderStruct 102 { 103 // watch out for alignment -- need to be on 4 byte chunks 104 uint16_t Common; ///< Common part of the header, 16 bit 105 uint16_t SeqNumber; ///< Sequence Number 106 uint32_t TimeStamp; ///< Time Stamp 107 }; 108 109 110 111 //####################################################################### 112 //####################### PacketHeader ################################## 113 //####################################################################### 114 /** \brief Base class for header type. Subclass this struct to 115 * create a new header. 116 */ 117 class PacketHeader : public QObject 118 { 119 Q_OBJECT; 120 121 public: 122 /// \brief The class Constructor 123 PacketHeader(JackTrip* jacktrip); 124 /// \brief The class Destructor ~PacketHeader()125 virtual ~PacketHeader() {} 126 127 /// \brief Return a time stamp in microseconds 128 /// \return Time stamp: microseconds since midnight (0 hour), January 1, 1970 129 static uint64_t usecTime(); 130 /// \todo Implement this using a JackTrip Method (Mediator) member instead of the 131 /// reference to JackAudio 132 virtual void fillHeaderCommonFromAudio() = 0; 133 /// \brief Parse the packet header and take appropriate measures (like change settings, or 134 /// quit the program if peer settings don't match) 135 virtual void parseHeader() = 0; 136 virtual void checkPeerSettings(int8_t* full_packet) = 0; 137 138 virtual uint64_t getPeerTimeStamp(int8_t* full_packet) const = 0; 139 virtual uint16_t getPeerSequenceNumber(int8_t* full_packet) const = 0; 140 virtual uint16_t getPeerBufferSize(int8_t* full_packet) const = 0; 141 virtual uint8_t getPeerSamplingRate(int8_t* full_packet) const = 0; 142 virtual uint8_t getPeerBitResolution(int8_t* full_packet) const = 0; 143 virtual uint8_t getPeerNumChannels(int8_t* full_packet) const = 0; 144 virtual uint8_t getPeerConnectionMode(int8_t* full_packet) const = 0; 145 146 /// \brief Increase sequence number for counter, a 16bit number increaseSequenceNumber()147 virtual void increaseSequenceNumber() 148 { mSeqNumber++; } 149 /// \brief Returns the current sequence number 150 /// \return 16bit Sequence number getSequenceNumber()151 virtual uint16_t getSequenceNumber() const 152 { return mSeqNumber; } 153 /// \brief Get the header size in bytes 154 virtual int getHeaderSizeInBytes() const = 0; putHeaderInPacketBaseClass(int8_t * full_packet,const HeaderStruct & header_struct)155 virtual void putHeaderInPacketBaseClass(int8_t* full_packet, 156 const HeaderStruct& header_struct) 157 { 158 std::memcpy(full_packet, reinterpret_cast<const void*>(&header_struct), 159 getHeaderSizeInBytes() ); 160 } 161 /// \brief Put the header in buffer pointed by full_packet 162 /// \param full_packet Pointer to full packet (audio+header). Size must be 163 /// sizeof(header part) + sizeof(audio part) 164 virtual void putHeaderInPacket(int8_t* full_packet) = 0; 165 166 167 signals: 168 void signalError(const QString &error_message); 169 170 171 private: 172 uint16_t mSeqNumber; 173 JackTrip* mJackTrip; ///< JackTrip mediator class 174 }; 175 176 177 178 179 //####################################################################### 180 //####################### DefaultHeader ################################# 181 //####################################################################### 182 /** \brief Default Header 183 */ 184 class DefaultHeader : public PacketHeader 185 { 186 public: 187 188 DefaultHeader(JackTrip* jacktrip); ~DefaultHeader()189 virtual ~DefaultHeader() {} 190 191 virtual void fillHeaderCommonFromAudio(); parseHeader()192 virtual void parseHeader() {} 193 virtual void checkPeerSettings(int8_t* full_packet); increaseSequenceNumber()194 virtual void increaseSequenceNumber() 195 { mHeader.SeqNumber++; } getSequenceNumber()196 virtual uint16_t getSequenceNumber() const 197 { return mHeader.SeqNumber; } getHeaderSizeInBytes()198 virtual int getHeaderSizeInBytes() const { return sizeof(mHeader); } putHeaderInPacket(int8_t * full_packet)199 virtual void putHeaderInPacket(int8_t* full_packet) 200 { putHeaderInPacketBaseClass(full_packet, mHeader); } 201 void printHeader() const; getConnectionMode()202 uint8_t getConnectionMode() const 203 { return mHeader.ConnectionMode; } getNumChannels()204 uint8_t getNumChannels() const 205 { return mHeader.NumChannels; } 206 207 208 virtual uint64_t getPeerTimeStamp(int8_t* full_packet) const; 209 virtual uint16_t getPeerSequenceNumber(int8_t* full_packet) const; 210 virtual uint16_t getPeerBufferSize(int8_t* full_packet) const; 211 virtual uint8_t getPeerSamplingRate(int8_t* full_packet) const; 212 virtual uint8_t getPeerBitResolution(int8_t* full_packet) const; 213 virtual uint8_t getPeerNumChannels(int8_t* full_packet) const; 214 virtual uint8_t getPeerConnectionMode(int8_t* full_packet) const; 215 216 217 private: 218 DefaultHeaderStruct mHeader;///< Default Header Struct 219 JackTrip* mJackTrip; ///< JackTrip mediator class 220 }; 221 222 223 224 225 //####################################################################### 226 //####################### JamLinkHeader ################################# 227 //####################################################################### 228 229 /** \brief JamLink Header 230 */ 231 class JamLinkHeader : public PacketHeader 232 { 233 public: 234 235 JamLinkHeader(JackTrip* jacktrip); ~JamLinkHeader()236 virtual ~JamLinkHeader() {} 237 238 virtual void fillHeaderCommonFromAudio(); parseHeader()239 virtual void parseHeader() {} checkPeerSettings(int8_t *)240 virtual void checkPeerSettings(int8_t* /*full_packet*/) {} 241 getPeerTimeStamp(int8_t *)242 virtual uint64_t getPeerTimeStamp(int8_t* /*full_packet*/) const { return 0; } getPeerSequenceNumber(int8_t *)243 virtual uint16_t getPeerSequenceNumber(int8_t* /*full_packet*/) const { return 0; } getPeerBufferSize(int8_t *)244 virtual uint16_t getPeerBufferSize(int8_t* /*full_packet*/) const { return 0; } getPeerSamplingRate(int8_t *)245 virtual uint8_t getPeerSamplingRate(int8_t* /*full_packet*/) const { return 0; } getPeerBitResolution(int8_t *)246 virtual uint8_t getPeerBitResolution(int8_t* /*full_packet*/) const { return 0; } getPeerNumChannels(int8_t *)247 virtual uint8_t getPeerNumChannels(int8_t* /*full_packet*/) const { return 0; } getPeerConnectionMode(int8_t *)248 virtual uint8_t getPeerConnectionMode(int8_t* /*full_packet*/) const { return 0; } 249 increaseSequenceNumber()250 virtual void increaseSequenceNumber() {} getHeaderSizeInBytes()251 virtual int getHeaderSizeInBytes() const { return sizeof(mHeader); } putHeaderInPacket(int8_t * full_packet)252 virtual void putHeaderInPacket(int8_t* full_packet) 253 { putHeaderInPacketBaseClass(full_packet, mHeader); } 254 255 private: 256 JamLinkHeaderStuct mHeader; ///< JamLink Header Struct 257 JackTrip* mJackTrip; ///< JackTrip mediator class 258 }; 259 260 261 262 //####################################################################### 263 //####################### EmptyHeader ################################# 264 //####################################################################### 265 266 /** \brief Empty Header to use with systems that don't include a header. 267 */ 268 class EmptyHeader : public PacketHeader 269 { 270 public: 271 272 EmptyHeader(JackTrip* jacktrip); ~EmptyHeader()273 virtual ~EmptyHeader() {} 274 fillHeaderCommonFromAudio()275 virtual void fillHeaderCommonFromAudio() {} parseHeader()276 virtual void parseHeader() {} checkPeerSettings(int8_t *)277 virtual void checkPeerSettings(int8_t* /*full_packet*/) {} increaseSequenceNumber()278 virtual void increaseSequenceNumber() {} getHeaderSizeInBytes()279 virtual int getHeaderSizeInBytes() const { return 0; } 280 getPeerTimeStamp(int8_t *)281 virtual uint64_t getPeerTimeStamp(int8_t* /*full_packet*/) const { return 0; } getPeerSequenceNumber(int8_t *)282 virtual uint16_t getPeerSequenceNumber(int8_t* /*full_packet*/) const { return 0; } getPeerBufferSize(int8_t *)283 virtual uint16_t getPeerBufferSize(int8_t* /*full_packet*/) const { return 0; } getPeerSamplingRate(int8_t *)284 virtual uint8_t getPeerSamplingRate(int8_t* /*full_packet*/) const { return 0; } getPeerBitResolution(int8_t *)285 virtual uint8_t getPeerBitResolution(int8_t* /*full_packet*/) const { return 0; } getPeerNumChannels(int8_t *)286 virtual uint8_t getPeerNumChannels(int8_t* /*full_packet*/) const { return 0; } getPeerConnectionMode(int8_t *)287 virtual uint8_t getPeerConnectionMode(int8_t* /*full_packet*/) const { return 0; } 288 putHeaderInPacket(int8_t *)289 virtual void putHeaderInPacket(int8_t* /*full_packet*/) {} 290 291 private: 292 JackTrip* mJackTrip; ///< JackTrip mediator class 293 }; 294 295 296 #endif //__PACKETHEADER_H__ 297