play.h

Go to the documentation of this file.
00001 /*
00002  * SpanDSP - a series of DSP components for telephony
00003  *
00004  * jitterbuffer.h - 
00005  *
00006  * Written by Steve Underwood <steveu@coppice.org>
00007  *
00008  * Copyright (C) 2007 Steve Underwood
00009  *
00010  * All rights reserved.
00011  *
00012  * This program is free software; you can redistribute it and/or modify
00013  * it under the terms of the GNU Lesser General Public License version 2.1,
00014  * as published by the Free Software Foundation.
00015  *
00016  * This program is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU Lesser General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU Lesser General Public
00022  * License along with this program; if not, write to the Free Software
00023  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00024  *
00025  * $Id$
00026  */
00027 
00028 /*! \file */
00029 
00030 #if !defined(_SPANDSP_PLAYOUTBUFFER_H_)
00031 #define _SPANDSP_PLAYOUTBUFFER_H_
00032 
00033 /*! \page playoutbuffer_page Playout buffering
00034 
00035 \section playoutbuffer_page_sec_1 What does it do?
00036 
00037 \section playoutbuffer_page_sec_2 How does it work?
00038 */
00039 
00040 #include "SampleArray.h"
00041 #include "AmStats.h"
00042 #include "LowcFE.h"
00043 #include "AmJitterBuffer.h"
00044 #include <set>
00045 using std::multiset;
00046 
00047 #define ORDER_STAT_WIN_SIZE  35
00048 #define ORDER_STAT_LOSS_RATE 0.1
00049 
00050 #define EXP_THRESHOLD 20
00051 #define SHR_THRESHOLD 180
00052 
00053 #define WSOLA_START_OFF  80
00054 #define WSOLA_SCALED_WIN 50
00055 
00056 // the maximum packet size that will be processed
00057 //   640 is 80ms @ 8kHz
00058 #define MAX_PACKET_SAMPLES 640
00059 // search segments of size TEMPLATE_SEG samples 
00060 #define TEMPLATE_SEG   80
00061 
00062 // Maximum value: AUDIO_BUFFER_SIZE / 2
00063 // Note: plc result get stored in our back buffer
00064 #define PLC_MAX_SAMPLES (160*4) 
00065 
00066 class AmPLCBuffer;
00067 
00068 /** \brief base class for Playout buffer */
00069 class AmPlayoutBuffer
00070 {
00071     // Playout buffer
00072     SampleArrayShort buffer;
00073 
00074  protected:
00075     uint32_t r_ts;
00076     uint32_t w_ts;
00077     AmPLCBuffer *m_plcbuffer;
00078 
00079     uint32_t last_ts;
00080     bool last_ts_i;
00081 
00082     /* The offset RTP receive TS <-> audio_buffer TS */ 
00083     uint32_t recv_offset;
00084     /* The recv_offset initialized ?  */ 
00085     bool recv_offset_i;
00086 
00087     void buffer_put(uint32_t ts, int16_t *buf, int len);
00088     void buffer_get(uint32_t ts, int16_t *buf, int len);
00089 
00090     virtual void write_buffer(uint32_t ref_ts, uint32_t ts, int16_t *buf, int len);
00091     virtual void direct_write_buffer(uint32_t ts, int16_t *buf, int len);
00092  public:
00093     AmPlayoutBuffer(AmPLCBuffer *plcbuffer);
00094     virtual ~AmPlayoutBuffer() {}
00095 
00096     virtual void write(uint32_t ref_ts, uint32_t ts, int16_t *buf, int len, bool begin_talk);
00097     virtual uint32_t read(uint32_t ts, int16_t *buf, int len);
00098 
00099     void clearLastTs() {last_ts_i = false;}
00100 };
00101 
00102 /** \brief adaptive playout buffer */
00103 class AmAdaptivePlayout: public AmPlayoutBuffer
00104 {
00105     // Order statistics delay estimation
00106     multiset<int32_t> o_stat;
00107     int32_t n_stat[ORDER_STAT_WIN_SIZE];
00108     int idx;
00109     double loss_rate;
00110 
00111     // Adaptive WSOLA
00112     uint32_t wsola_off;
00113     int shr_threshold;
00114     MeanArray short_scaled;
00115 
00116     // Second stage PLC
00117     int plc_cnt;
00118     LowcFE fec;
00119 
00120     // Buffers
00121     // stretch buffer
00122     int16_t p_buf[MAX_PACKET_SAMPLES*4];
00123     // Merging buffer (merge segment from strech + original seg)
00124     int16_t merge_buf[TEMPLATE_SEG];
00125 
00126     uint32_t time_scale(uint32_t ts, float factor, uint32_t packet_len);
00127     uint32_t next_delay(uint32_t ref_ts, uint32_t ts);
00128 
00129 public:
00130     AmAdaptivePlayout(AmPLCBuffer *);
00131 
00132     /* Write len samples beginning from timestamp ts from buf */
00133     void direct_write_buffer(unsigned int ts, int16_t *buf, unsigned int len);
00134 
00135     /* Write len samples which beginn from timestamp ts from buf
00136        reference ts of buffer (monotonic increasing buffer ts) is ref_ts */
00137     void write_buffer(uint32_t ref_ts, uint32_t ts, int16_t *buf, uint32_t len);
00138 
00139     /* Read len samples beginn from timestamp ts into buf */
00140     uint32_t read(uint32_t ts, int16_t *buf, uint32_t len);
00141 };
00142 
00143 /** \brief adaptive jitter buffer */
00144 class AmJbPlayout : public AmPlayoutBuffer
00145 {
00146 private:
00147     AmJitterBuffer m_jb;
00148     unsigned int m_last_rtp_endts;
00149 
00150 protected:
00151     void direct_write_buffer(unsigned int ts, int16_t *buf, unsigned int len);
00152     void prepare_buffer(unsigned int ts, unsigned int ms);
00153 
00154 public:
00155     AmJbPlayout(AmPLCBuffer *plcbuffer);
00156 
00157     uint32_t read(uint32_t ts, int16_t *buf, uint32_t len);
00158     void write(uint32_t ref_ts, uint32_t rtp_ts, int16_t *buf, uint32_t len, bool begin_talk);
00159 };
00160 
00161 #if defined(__cplusplus)
00162 extern "C"
00163 {
00164 #endif
00165 
00166 #if defined(__cplusplus)
00167 }
00168 #endif
00169 
00170 #endif
00171 /*- End of file ------------------------------------------------------------*/

Generated on Tue Oct 7 20:25:47 2008 for spandsp by  doxygen 1.5.6