1 /*
2  * Copyright (C) 2002-2003 Fhg Fokus
3  *
4  * This file is part of SEMS, a free SIP media server.
5  *
6  * SEMS is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version. This program is released under
10  * the GPL with the additional exemption that compiling, linking,
11  * and/or using OpenSSL is allowed.
12  *
13  * For a license to use the SEMS software under conditions
14  * other than those described here, or to purchase support for this
15  * software, please contact iptel.org by e-mail at the following addresses:
16  *    info@iptel.org
17  *
18  * SEMS is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26  */
27 /** @file AmRtpAudio.h */
28 #ifndef _AmRtpAudio_h_
29 #define _AmRtpAudio_h_
30 
31 #include "AmAudio.h"
32 #include "AmRtpStream.h"
33 #include "LowcFE.h"
34 
35 #ifdef USE_SPANDSP_PLC
36 #include <math.h>
37 #include "spandsp/plc.h"
38 #endif
39 
40 class AmPlayoutBuffer;
41 
42 enum PlayoutType {
43   ADAPTIVE_PLAYOUT,
44   JB_PLAYOUT,
45   SIMPLE_PLAYOUT
46 };
47 
48 
49 
50 /**
51  * \brief interface for PLC buffer
52  */
53 
54 class AmPLCBuffer {
55  public:
56 
57   virtual void add_to_history(int16_t *buffer, unsigned int size) = 0;
58 
59   // Conceals packet loss into the out_buffer
60   // @return length in bytes of the recivered segment
61   virtual unsigned int conceal_loss(unsigned int ts_diff, unsigned char *out_buffer) = 0;
AmPLCBuffer()62   AmPLCBuffer() { }
~AmPLCBuffer()63   virtual ~AmPLCBuffer() { }
64 };
65 
66 
67 /** \brief RTP audio format */
68 class AmAudioRtpFormat: public AmAudioFormat
69 {
70   /** Sampling rate as advertized in SDP (differs from actual rate for G722) **/
71   unsigned int advertized_rate;
72 
73 protected:
74   /* frame size in samples */
75   unsigned int frame_size;
76 
77   /** from AmAudioFormat */
78   void initCodec();
79 
80 public:
81   AmAudioRtpFormat();
82   ~AmAudioRtpFormat();
83 
84   /** return the timestamp sampling rate */
getTSRate()85   unsigned int getTSRate() { return advertized_rate; }
getFrameSize()86   unsigned int getFrameSize() { return frame_size; }
87 
88   /**
89    * changes payload. returns != 0 on error.
90    */
91   int setCurrentPayload(Payload pl);
92 };
93 
94 
95 /**
96  * \brief binds together a \ref AmRtpStream and an \ref AmAudio for a session
97  */
98 class AmRtpAudio: public AmRtpStream, public AmAudio, public AmPLCBuffer
99 {
100   PlayoutType m_playout_type;
101   std::unique_ptr<AmPlayoutBuffer> playout_buffer;
102 
103 #ifdef USE_SPANDSP_PLC
104     plc_state_t* plc_state;
105 #else
106     std::unique_ptr<LowcFE>       fec;
107 #endif
108 
109   bool         use_default_plc;
110 
111   unsigned long long last_check;
112   bool               last_check_i;
113   bool               send_int;
114 
115   unsigned long long last_send_ts;
116   bool               last_send_ts_i;
117 
118   //
119   // Default packet loss concealment functions
120   //
121   unsigned int default_plc(unsigned char* out_buf,
122 			   unsigned int   size,
123 			   unsigned int   channels,
124 			   unsigned int   rate);
125 
126 public:
127   AmRtpAudio(AmSession* _s, int _if);
128   ~AmRtpAudio();
129 
130   unsigned int getFrameSize();
131 
132   bool checkInterval(unsigned long long ts);
133   bool sendIntReached();
134   bool sendIntReached(unsigned long long ts);
135 
136   int setCurrentPayload(int payload);
137   int getCurrentPayload();
138 
139   int receive(unsigned long long system_ts);
140 
141   // AmAudio interface
142   int get(unsigned long long system_ts, unsigned char* buffer,
143 	  int output_sample_rate, unsigned int nb_samples);
144 
145   int put(unsigned long long system_ts, unsigned char* buffer,
146 	  int input_sample_rate, unsigned int size);
147 
148   unsigned int bytes2samples(unsigned int) const;
149 
150   // AmRtpStream interface
151   void getSdpOffer(unsigned int index, SdpMedia& offer);
152   void getSdpAnswer(unsigned int index, const SdpMedia& offer, SdpMedia& answer);
153 
154   int init(const AmSdp& local,
155 	   const AmSdp& remote, bool force_symmetric_rtp = false);
156 
157   void setPlayoutType(PlayoutType type);
158 
159 
160   // AmPLCBuffer interface
161   void add_to_history(int16_t *buffer, unsigned int size);
162 
163   // Conceals packet loss into the out_buffer
164   // @return length in bytes of the recivered segment
165   unsigned int conceal_loss(unsigned int ts_diff, unsigned char *out_buffer);
166 
167 protected:
read(unsigned int user_ts,unsigned int size)168   int read(unsigned int user_ts, unsigned int size) { return 0; }
write(unsigned int user_ts,unsigned int size)169   int write(unsigned int user_ts, unsigned int size) { return 0; }
170 };
171 
172 #endif
173 
174 
175 
176 
177 
178 
179