1 // ----------------------------------------------------------------------------
2 //
3 //  Copyright (C) 2013-2016 Fons Adriaensen <fons@linuxaudio.org>
4 //
5 //  This program is free software; you can redistribute it and/or modify
6 //  it under the terms of the GNU General Public License as published by
7 //  the Free Software Foundation; either version 3 of the License, or
8 //  (at your option) any later version.
9 //
10 //  This program is distributed in the hope that it will be useful,
11 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //  GNU General Public License for more details.
14 //
15 //  You should have received a copy of the GNU General Public License
16 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 //
18 // ----------------------------------------------------------------------------
19 
20 
21 #ifndef __NETDATA_H
22 #define __NETDATA_H
23 
24 
25 #include <stdint.h>
26 
27 // This class defines the encoding of network packets.
28 // All data uses network byte order.
29 //
30 class Netdata
31 {
32 public:
33 
34     Netdata (int size);
35     ~Netdata (void);
36 
37     enum { MAXCHAN = 64 };
38     enum
39     {
40         FM_16BIT,
41         FM_24BIT,
42         FM_FLOAT,
43     };
44     enum
45     {
46         TY_ADESC,  // Audio descriptor packet.
47         TY_ADATA   // Audio sample data packet.
48     };
49     enum
50     {
51         FL_TIMED  = 0x01, // Valid dtime field, start of period.
52         FL_SUSP   = 0x02, // Transmission is suspended.
53 	FL_SKIP   = 0x04, // Token packet for skipped frames.
54         FL_TERM   = 0x80  // Sender terminates.
55     };
56 
data(void)57     unsigned char *data (void) const { return _data; }
size(void)58     int size (void) const { return _size; } // Allocated size, normally MTU.
dlen(void)59     int dlen (void) const { return _dlen; } // Used size in bytes.
60 
61     void init_audio_desc (int flags, int sform, int nchan, int psmax, int fsamp, int fsize);
62     void init_audio_data (int flags, int sform, int nchan, int count, int nfram, int dtime);
set_flags(int flags)63     void set_flags (int flags) { _data [FLAGS] = flags; }
64     void set_tmark (int32_t tfcnt, uint32_t tsecs, uint32_t tfrac);
65 
66     int check_ptype (void) const;
get_ptype(void)67     int get_ptype (void) const { return _data [PTYPE]; }   // Packet type (TY_xxx)
get_flags(void)68     int get_flags (void) const { return _data [FLAGS]; }   // Various flags (FL_xxx)
get_sform(void)69     int get_sform (void) const { return _data [SFORM]; }   // Sample format (FM_xxx)
get_nchan(void)70     int get_nchan (void) const { return _data [NCHAN]; }   // Number of channels.
get_psmax(void)71     int get_psmax (void) const { return getint (PSMAX); }  // Maximum packet size.
get_fsamp(void)72     int get_fsamp (void) const { return getint (FSAMP); }  // Sender sample frequency.
get_fsize(void)73     int get_fsize (void) const { return getint (FSIZE); }  // Sender period size.
get_tfcnt(void)74     int get_tfcnt (void) const { return getint (TFCNT); }  // Timestamp frame count.
get_tsecs(void)75     int get_tsecs (void) const { return getint (TSECS); }  // Timestamp NTP seconds.
get_tfrac(void)76     int get_tfrac (void) const { return getint (TFRAC); }  // Timestamp NTP fraction.
get_count(void)77     int get_count (void) const { return getint (COUNT); }  // Frame count, used to check continuity.
get_nfram(void)78     int get_nfram (void) const { return getint (NFRAM); }  // Number of frames in this packet.
get_dtime(void)79     int get_dtime (void) const { return getint (DTIME); }  // Transmit delay in usecs.
80 
81     void put_audio (int chan, int offs, int nsamp, const float *adata, int astep);
82     void get_audio (int chan, int offs, int nsamp, float *adata, int astep) const;
83 
84     static int packetsperperiod (int maxsize, int period, int sform, int nchan);
85 
86 private:
87 
88     // Byte offsets.
89     enum
90     {
91 	// All packets
92 	PTYPE = 4,
93 	FLAGS = 5,
94 
95 	// All audio packets
96 	SFORM = 6,
97 	NCHAN = 7,
98 
99 	// Descriptor packet
100 	PSMAX = 8,
101 	FSAMP = 12,
102 	FSIZE = 16,
103 	TFCNT = 20,
104 	TSECS = 24,
105 	TFRAC = 28,
106 	DPEND = 32,
107 
108 	// Sample data packet
109 	COUNT = 8,
110 	NFRAM = 12,
111 	DTIME = 16,
112 	ADATA = 20
113     };
114 
115     void init_header (int ptype, int flags, int sform, int nchan);
116 
117     // Used for header fields, always big-endian.
118     // Put a 32-bit integer.
putint(int k,int32_t v)119     void putint (int k, int32_t v)
120     {
121 	_data [k++] = v >> 24;
122 	_data [k++] = v >> 16;
123 	_data [k++] = v >> 8;
124 	_data [k++] = v;
125     }
126     // Get a 32-bit integer.
getint(int k)127     int32_t getint (int k) const
128     {
129 	int32_t v;
130 	v  = _data [k++] << 24;
131 	v += _data [k++] << 16;
132 	v += _data [k++] << 8;
133 	v += _data [k++];
134 	return v;
135     }
136 
137     int             _size;  // Allocated size.
138     int             _dlen;  // Used size.
139     unsigned char  *_data;
140 };
141 
142 
143 #endif
144