1 /*
2  * Copyright (C) 2005-2006 iptelorg GmbH
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 AmPlayoutBuffer.h */
28 #ifndef _AmPlayoutBuffer_h_
29 #define _AmPlayoutBuffer_h_
30 
31 #include "SampleArray.h"
32 #include "AmStats.h"
33 #include "LowcFE.h"
34 #include "AmJitterBuffer.h"
35 #include <set>
36 using std::multiset;
37 
38 
39 #define ORDER_STAT_WIN_SIZE  35
40 #define ORDER_STAT_LOSS_RATE 0.1
41 
42 #define EXP_THRESHOLD 20
43 #define SHR_THRESHOLD 180
44 
45 #define WSOLA_START_OFF  10 * sample_rate / 1000
46 #define WSOLA_SCALED_WIN 50
47 
48 // the maximum packet size that will be processed (80ms)
49 #define MAX_PACKET_SAMPLES 80 * SYSTEM_SAMPLECLOCK_RATE / 1000
50 // search segments of size TEMPLATE_SEG samples (10 ms)
51 #define TEMPLATE_SEG   10 * sample_rate / 1000
52 #define STATIC_TEMPLATE_SEG   10 * SYSTEM_SAMPLECLOCK_RATE / 1000
53 
54 // Maximum value: AUDIO_BUFFER_SIZE / 2
55 // Note: plc result get stored in our back buffer
56 // maximum of 80ms PLC
57 #define PLC_MAX_SAMPLES (4*20*sample_rate / 1000)
58 
59 class AmPLCBuffer;
60 
61 /** \brief base class for Playout buffer */
62 class AmPlayoutBuffer
63 {
64   // Playout buffer
65   SampleArrayShort buffer;
66 
67  protected:
68   u_int32_t r_ts,w_ts;
69   AmPLCBuffer *m_plcbuffer;
70 
71   unsigned int last_ts;
72   bool         last_ts_i;
73 
74   unsigned int sample_rate;
75 
76   /** the offset RTP receive TS <-> audio_buffer TS */
77   unsigned int   recv_offset;
78   /** the recv_offset initialized ?  */
79   bool           recv_offset_i;
80 
81   void buffer_put(unsigned int ts, ShortSample* buf, unsigned int len);
82   void buffer_get(unsigned int ts, ShortSample* buf, unsigned int len);
83 
84   virtual void write_buffer(u_int32_t ref_ts, u_int32_t ts, int16_t* buf, u_int32_t len);
85   virtual void direct_write_buffer(unsigned int ts, ShortSample* buf, unsigned int len);
86  public:
87   AmPlayoutBuffer(AmPLCBuffer *plcbuffer, unsigned int sample_rate);
~AmPlayoutBuffer()88   virtual ~AmPlayoutBuffer() {}
89 
90   virtual void write(u_int32_t ref_ts, u_int32_t ts, int16_t* buf, u_int32_t len, bool begin_talk);
91   virtual u_int32_t read(u_int32_t ts, int16_t* buf, u_int32_t len);
92 
clearLastTs()93   void clearLastTs() { last_ts_i = false; }
94 };
95 
96 /** \brief adaptive playout buffer */
97 class AmAdaptivePlayout: public AmPlayoutBuffer
98 {
99   // Order statistics delay estimation
100   multiset<int32_t> o_stat;
101   int32_t n_stat[ORDER_STAT_WIN_SIZE];
102   int     idx;
103   double  loss_rate;
104 
105   // adaptive WSOLA
106   u_int32_t wsola_off;
107   int       shr_threshold;
108   MeanArray short_scaled;
109 
110   // second stage PLC
111   int       plc_cnt;
112   LowcFE    fec;
113 
114   // buffers
115   // strech buffer
116   short p_buf[MAX_PACKET_SAMPLES*4];
117   // merging buffer (merge segment from strech + original seg)
118   short merge_buf[STATIC_TEMPLATE_SEG];
119 
120   u_int32_t time_scale(u_int32_t ts, float factor, u_int32_t packet_len);
121   u_int32_t next_delay(u_int32_t ref_ts, u_int32_t ts);
122 
123  public:
124 
125   AmAdaptivePlayout(AmPLCBuffer *, unsigned int sample_rate);
126 
127   /** write len samples beginning from timestamp ts from buf */
128   void direct_write_buffer(unsigned int ts, ShortSample* buf, unsigned int len);
129 
130   /** write len samples which beginn from timestamp ts from buf
131       reference ts of buffer (monotonic increasing buffer ts) is ref_ts */
132   void write_buffer(u_int32_t ref_ts, u_int32_t ts, int16_t* buf, u_int32_t len);
133 
134   /** read len samples beginn from timestamp ts into buf */
135   u_int32_t read(u_int32_t ts, int16_t* buf, u_int32_t len);
136 
137 };
138 
139 /** \brief adaptive jitter buffer */
140 class AmJbPlayout : public AmPlayoutBuffer
141 {
142  private:
143   AmJitterBuffer m_jb;
144   unsigned int m_last_rtp_endts;
145 
146  protected:
147   void direct_write_buffer(unsigned int ts, ShortSample* buf, unsigned int len);
148   void prepare_buffer(unsigned int ts, unsigned int ms);
149 
150  public:
151   AmJbPlayout(AmPLCBuffer *plcbuffer, unsigned int sample_rate);
152 
153   u_int32_t read(u_int32_t ts, int16_t* buf, u_int32_t len);
154   void write(u_int32_t ref_ts, u_int32_t rtp_ts, int16_t* buf, u_int32_t len, bool begin_talk);
155 };
156 
157 
158 #endif
159