Asterisk - The Open Source Telephony Project GIT-master-f36a736
plc.h
Go to the documentation of this file.
1/*! \file
2 * \brief SpanDSP - a series of DSP components for telephony
3 *
4 * plc.h
5 *
6 * \author Steve Underwood <steveu@coppice.org>
7 *
8 * Copyright (C) 2004 Steve Underwood
9 *
10 * All rights reserved.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * This version may be optionally licenced under the GNU LGPL licence.
27 *
28 * A license has been granted to Digium (via disclaimer) for the use of
29 * this code.
30 */
31
32
33#if !defined(_PLC_H_)
34#define _PLC_H_
35
36/* solaris used to #include <sys/int_types.h> */
37
38/*! \page plc_page Packet loss concealment
39\section plc_page_sec_1 What does it do?
40The packet loss concealment module provides a suitable synthetic fill-in signal,
41to minimise the audible effect of lost packets in VoIP applications. It is not
42tied to any particular codec, and could be used with almost any codec which does not
43specify its own procedure for packet loss concealment.
44
45Where a codec specific concealment procedure exists, the algorithm is usually built
46around knowledge of the characteristics of the particular codec. It will, therefore,
47generally give better results for that particular codec than this generic concealer will.
48
49\section plc_page_sec_2 How does it work?
50While good packets are being received, the plc_rx() routine keeps a record of the trailing
51section of the known speech signal. If a packet is missed, plc_fillin() is called to produce
52a synthetic replacement for the real speech signal. The average mean difference function
53(AMDF) is applied to the last known good signal, to determine its effective pitch.
54Based on this, the last pitch period of signal is saved. Essentially, this cycle of speech
55will be repeated over and over until the real speech resumes. However, several refinements
56are needed to obtain smooth pleasant sounding results.
57
58- The two ends of the stored cycle of speech will not always fit together smoothly. This can
59 cause roughness, or even clicks, at the joins between cycles. To soften this, the
60 1/4 pitch period of real speech preceeding the cycle to be repeated is blended with the last
61 1/4 pitch period of the cycle to be repeated, using an overlap-add (OLA) technique (i.e.
62 in total, the last 5/4 pitch periods of real speech are used).
63
64- The start of the synthetic speech will not always fit together smoothly with the tail of
65 real speech passed on before the erasure was identified. Ideally, we would like to modify
66 the last 1/4 pitch period of the real speech, to blend it into the synthetic speech. However,
67 it is too late for that. We could have delayed the real speech a little, but that would
68 require more buffer manipulation, and hurt the efficiency of the no-lost-packets case
69 (which we hope is the dominant case). Instead we use a degenerate form of OLA to modify
70 the start of the synthetic data. The last 1/4 pitch period of real speech is time reversed,
71 and OLA is used to blend it with the first 1/4 pitch period of synthetic speech. The result
72 seems quite acceptable.
73
74- As we progress into the erasure, the chances of the synthetic signal being anything like
75 correct steadily fall. Therefore, the volume of the synthesized signal is made to decay
76 linearly, such that after 50ms of missing audio it is reduced to silence.
77
78- When real speech resumes, an extra 1/4 pitch period of synthetic speech is blended with the
79 start of the real speech. If the erasure is small, this smoothes the transition. If the erasure
80 is long, and the synthetic signal has faded to zero, the blending softens the start up of the
81 real signal, avoiding a kind of "click" or "pop" effect that might occur with a sudden onset.
82
83\section plc_page_sec_3 How do I use it?
84Before audio is processed, call plc_init() to create an instance of the packet loss
85concealer. For each received audio packet that is acceptable (i.e. not including those being
86dropped for being too late) call plc_rx() to record the content of the packet. Note this may
87modify the packet a little after a period of packet loss, to blend real synthetic data smoothly.
88When a real packet is not available in time, call plc_fillin() to create a synthetic substitute.
89That's it!
90*/
91
92/*! Minimum allowed pitch (66 Hz) */
93#define PLC_PITCH_MIN 120
94/*! Maximum allowed pitch (200 Hz) */
95#define PLC_PITCH_MAX 40
96/*! Maximum pitch OLA window */
97#define PLC_PITCH_OVERLAP_MAX (PLC_PITCH_MIN >> 2)
98/*! The length over which the AMDF function looks for similarity (20 ms) */
99#define CORRELATION_SPAN 160
100/*! History buffer length. The buffer much also be at leat 1.25 times
101 PLC_PITCH_MIN, but that is much smaller than the buffer needs to be for
102 the pitch assessment. */
103#define PLC_HISTORY_LEN (CORRELATION_SPAN + PLC_PITCH_MIN)
104
105typedef struct
106{
107 /*! Consecutive erased samples */
109 /*! Current offset into pitch period */
111 /*! Pitch estimate */
112 int pitch;
113 /*! Buffer for a cycle of speech */
114 float pitchbuf[PLC_PITCH_MIN];
115 /*! History buffer */
117 /*! Current pointer into the history buffer */
120
121
122#ifdef __cplusplus
123extern "C" {
124#endif
125
126/*! Process a block of received audio samples.
127 \brief Process a block of received audio samples.
128 \param s The packet loss concealer context.
129 \param amp The audio sample buffer.
130 \param len The number of samples in the buffer.
131 \return The number of samples in the buffer. */
132int plc_rx(plc_state_t *s, int16_t amp[], int len);
133
134/*! Fill-in a block of missing audio samples.
135 \brief Fill-in a block of missing audio samples.
136 \param s The packet loss concealer context.
137 \param amp The audio sample buffer.
138 \param len The number of samples to be synthesised.
139 \return The number of samples synthesized. */
140int plc_fillin(plc_state_t *s, int16_t amp[], int len);
141
142/*! Process a block of received V.29 modem audio samples.
143 \brief Process a block of received V.29 modem audio samples.
144 \param s The packet loss concealer context.
145 \return A pointer to the he packet loss concealer context. */
147
148#ifdef __cplusplus
149}
150#endif
151
152#endif
153/*- End of file ------------------------------------------------------------*/
short int16_t
Definition: db.h:59
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int plc_fillin(plc_state_t *s, int16_t amp[], int len)
Fill-in a block of missing audio samples.
Definition: plc.c:175
#define PLC_HISTORY_LEN
Definition: plc.h:103
#define PLC_PITCH_MIN
Definition: plc.h:93
plc_state_t * plc_init(plc_state_t *s)
Process a block of received V.29 modem audio samples.
Definition: plc.c:244
int plc_rx(plc_state_t *s, int16_t amp[], int len)
Process a block of received audio samples.
Definition: plc.c:132
int pitch_offset
Definition: plc.h:110
int pitch
Definition: plc.h:112
int missing_samples
Definition: plc.h:108
int buf_ptr
Definition: plc.h:118