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