Mon Oct 8 12:39:04 2012

Asterisk developer's documentation


plc.h

Go to the documentation of this file.
00001 /*! \file
00002  * \brief SpanDSP - a series of DSP components for telephony
00003  *
00004  * plc.h
00005  *
00006  * \author Steve Underwood <steveu@coppice.org>
00007  *
00008  * Copyright (C) 2004 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 General Public License as published by
00014  * the Free Software Foundation; either version 2 of the License, or
00015  * (at your option) any later version.
00016  *
00017  * This program is distributed in the hope that it will be useful,
00018  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020  * GNU General Public License for more details.
00021  *
00022  * You should have received a copy of the GNU General Public License
00023  * along with this program; if not, write to the Free Software
00024  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00025  *
00026  * This version may be optionally licenced under the GNU LGPL licence.
00027  *
00028  * A license has been granted to Digium (via disclaimer) for the use of
00029  * this code.
00030  */
00031 
00032 
00033 #if !defined(_PLC_H_)
00034 #define _PLC_H_
00035 
00036 /* solaris used to #include <sys/int_types.h> */
00037 
00038 /*! \page plc_page Packet loss concealment
00039 \section plc_page_sec_1 What does it do?
00040 The packet loss concealment module provides a suitable synthetic fill-in signal,
00041 to minimise the audible effect of lost packets in VoIP applications. It is not
00042 tied to any particular codec, and could be used with almost any codec which does not
00043 specify its own procedure for packet loss concealment.
00044 
00045 Where a codec specific concealment procedure exists, the algorithm is usually built
00046 around knowledge of the characteristics of the particular codec. It will, therefore,
00047 generally give better results for that particular codec than this generic concealer will.
00048 
00049 \section plc_page_sec_2 How does it work?
00050 While good packets are being received, the plc_rx() routine keeps a record of the trailing
00051 section of the known speech signal. If a packet is missed, plc_fillin() is called to produce
00052 a synthetic replacement for the real speech signal. The average mean difference function
00053 (AMDF) is applied to the last known good signal, to determine its effective pitch.
00054 Based on this, the last pitch period of signal is saved. Essentially, this cycle of speech
00055 will be repeated over and over until the real speech resumes. However, several refinements
00056 are needed to obtain smooth pleasant sounding results.
00057 
00058 - The two ends of the stored cycle of speech will not always fit together smoothly. This can
00059   cause roughness, or even clicks, at the joins between cycles. To soften this, the
00060   1/4 pitch period of real speech preceeding the cycle to be repeated is blended with the last
00061   1/4 pitch period of the cycle to be repeated, using an overlap-add (OLA) technique (i.e.
00062   in total, the last 5/4 pitch periods of real speech are used).
00063 
00064 - The start of the synthetic speech will not always fit together smoothly with the tail of
00065   real speech passed on before the erasure was identified. Ideally, we would like to modify
00066   the last 1/4 pitch period of the real speech, to blend it into the synthetic speech. However,
00067   it is too late for that. We could have delayed the real speech a little, but that would
00068   require more buffer manipulation, and hurt the efficiency of the no-lost-packets case
00069   (which we hope is the dominant case). Instead we use a degenerate form of OLA to modify
00070   the start of the synthetic data. The last 1/4 pitch period of real speech is time reversed,
00071   and OLA is used to blend it with the first 1/4 pitch period of synthetic speech. The result
00072   seems quite acceptable.
00073 
00074 - As we progress into the erasure, the chances of the synthetic signal being anything like
00075   correct steadily fall. Therefore, the volume of the synthesized signal is made to decay
00076   linearly, such that after 50ms of missing audio it is reduced to silence.
00077 
00078 - When real speech resumes, an extra 1/4 pitch period of sythetic speech is blended with the
00079   start of the real speech. If the erasure is small, this smoothes the transition. If the erasure
00080   is long, and the synthetic signal has faded to zero, the blending softens the start up of the
00081   real signal, avoiding a kind of "click" or "pop" effect that might occur with a sudden onset.
00082 
00083 \section plc_page_sec_3 How do I use it?
00084 Before audio is processed, call plc_init() to create an instance of the packet loss
00085 concealer. For each received audio packet that is acceptable (i.e. not including those being
00086 dropped for being too late) call plc_rx() to record the content of the packet. Note this may
00087 modify the packet a little after a period of packet loss, to blend real synthetic data smoothly.
00088 When a real packet is not available in time, call plc_fillin() to create a sythetic substitute.
00089 That's it!
00090 */
00091 
00092 /*! Minimum allowed pitch (66 Hz) */
00093 #define PLC_PITCH_MIN           120
00094 /*! Maximum allowed pitch (200 Hz) */
00095 #define PLC_PITCH_MAX           40
00096 /*! Maximum pitch OLA window */
00097 #define PLC_PITCH_OVERLAP_MAX   (PLC_PITCH_MIN >> 2)
00098 /*! The length over which the AMDF function looks for similarity (20 ms) */
00099 #define CORRELATION_SPAN        160
00100 /*! History buffer length. The buffer much also be at leat 1.25 times
00101     PLC_PITCH_MIN, but that is much smaller than the buffer needs to be for
00102     the pitch assessment. */
00103 #define PLC_HISTORY_LEN         (CORRELATION_SPAN + PLC_PITCH_MIN)
00104 
00105 typedef struct
00106 {
00107     /*! Consecutive erased samples */
00108     int missing_samples;
00109     /*! Current offset into pitch period */
00110     int pitch_offset;
00111     /*! Pitch estimate */
00112     int pitch;
00113     /*! Buffer for a cycle of speech */
00114     float pitchbuf[PLC_PITCH_MIN];
00115     /*! History buffer */
00116     int16_t history[PLC_HISTORY_LEN];
00117     /*! Current pointer into the history buffer */
00118     int buf_ptr;
00119 } plc_state_t;
00120 
00121 
00122 #ifdef __cplusplus
00123 extern "C" {
00124 #endif
00125 
00126 /*! Process a block of received audio samples.
00127     \brief Process a block of received audio samples.
00128     \param s The packet loss concealer context.
00129     \param amp The audio sample buffer.
00130     \param len The number of samples in the buffer.
00131     \return The number of samples in the buffer. */
00132 int plc_rx(plc_state_t *s, int16_t amp[], int len);
00133 
00134 /*! Fill-in a block of missing audio samples.
00135     \brief Fill-in a block of missing audio samples.
00136     \param s The packet loss concealer context.
00137     \param amp The audio sample buffer.
00138     \param len The number of samples to be synthesised.
00139     \return The number of samples synthesized. */
00140 int plc_fillin(plc_state_t *s, int16_t amp[], int len);
00141 
00142 /*! Process a block of received V.29 modem audio samples.
00143     \brief Process a block of received V.29 modem audio samples.
00144     \param s The packet loss concealer context.
00145     \return A pointer to the he packet loss concealer context. */
00146 plc_state_t *plc_init(plc_state_t *s);
00147 
00148 #ifdef __cplusplus
00149 }
00150 #endif
00151 
00152 #endif
00153 /*- End of file ------------------------------------------------------------*/

Generated on Mon Oct 8 12:39:04 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7