Asterisk - The Open Source Telephony Project GIT-master-2de1a68
Data Structures | Macros | Functions
plc.h File Reference

SpanDSP - a series of DSP components for telephony. More...

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  plc_state_t
 

Macros

#define CORRELATION_SPAN   160
 
#define PLC_HISTORY_LEN   (CORRELATION_SPAN + PLC_PITCH_MIN)
 
#define PLC_PITCH_MAX   40
 
#define PLC_PITCH_MIN   120
 
#define PLC_PITCH_OVERLAP_MAX   (PLC_PITCH_MIN >> 2)
 

Functions

int plc_fillin (plc_state_t *s, int16_t amp[], int len)
 Fill-in a block of missing audio samples. More...
 
plc_state_tplc_init (plc_state_t *s)
 Process a block of received V.29 modem audio samples. More...
 
int plc_rx (plc_state_t *s, int16_t amp[], int len)
 Process a block of received audio samples. More...
 

Detailed Description

SpanDSP - a series of DSP components for telephony.

plc.h

Author
Steve Underwood steve.nosp@m.u@co.nosp@m.ppice.nosp@m..org

Copyright (C) 2004 Steve Underwood

All rights reserved.

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

This version may be optionally licenced under the GNU LGPL licence.

A license has been granted to Digium (via disclaimer) for the use of this code.

Definition in file plc.h.

Macro Definition Documentation

◆ CORRELATION_SPAN

#define CORRELATION_SPAN   160

The length over which the AMDF function looks for similarity (20 ms)

Definition at line 99 of file plc.h.

◆ PLC_HISTORY_LEN

#define PLC_HISTORY_LEN   (CORRELATION_SPAN + PLC_PITCH_MIN)

History buffer length. The buffer much also be at leat 1.25 times PLC_PITCH_MIN, but that is much smaller than the buffer needs to be for the pitch assessment.

Definition at line 103 of file plc.h.

◆ PLC_PITCH_MAX

#define PLC_PITCH_MAX   40

Maximum allowed pitch (200 Hz)

Definition at line 95 of file plc.h.

◆ PLC_PITCH_MIN

#define PLC_PITCH_MIN   120

Minimum allowed pitch (66 Hz)

Definition at line 93 of file plc.h.

◆ PLC_PITCH_OVERLAP_MAX

#define PLC_PITCH_OVERLAP_MAX   (PLC_PITCH_MIN >> 2)

Maximum pitch OLA window

Definition at line 97 of file plc.h.

Function Documentation

◆ plc_fillin()

int plc_fillin ( plc_state_t s,
int16_t  amp[],
int  len 
)

Fill-in a block of missing audio samples.

Fill-in a block of missing audio samples.

Parameters
sThe packet loss concealer context.
ampThe audio sample buffer.
lenThe number of samples to be synthesised.
Returns
The number of samples synthesized.

Definition at line 175 of file plc.c.

176{
177 int i;
178 int pitch_overlap;
179 float old_step;
180 float new_step;
181 float old_weight;
182 float new_weight;
183 float gain;
184 int orig_len;
185
186 orig_len = len;
187 if (s->missing_samples == 0) {
188 /* As the gap in real speech starts we need to assess the last known pitch,
189 and prepare the synthetic data we will use for fill-in */
192 /* We overlap a 1/4 wavelength */
193 pitch_overlap = s->pitch >> 2;
194 /* Cook up a single cycle of pitch, using a single of the real signal with 1/4
195 cycle OLA'ed to make the ends join up nicely */
196 /* The first 3/4 of the cycle is a simple copy */
197 for (i = 0; i < s->pitch - pitch_overlap; i++)
198 s->pitchbuf[i] = s->history[PLC_HISTORY_LEN - s->pitch + i];
199 /* The last 1/4 of the cycle is overlapped with the end of the previous cycle */
200 new_step = 1.0/pitch_overlap;
201 new_weight = new_step;
202 for ( ; i < s->pitch; i++) {
203 s->pitchbuf[i] = s->history[PLC_HISTORY_LEN - s->pitch + i] * (1.0 - new_weight) + s->history[PLC_HISTORY_LEN - 2 * s->pitch + i]*new_weight;
204 new_weight += new_step;
205 }
206 /* We should now be ready to fill in the gap with repeated, decaying cycles
207 of what is in pitchbuf */
208
209 /* We need to OLA the first 1/4 wavelength of the synthetic data, to smooth
210 it into the previous real data. To avoid the need to introduce a delay
211 in the stream, reverse the last 1/4 wavelength, and OLA with that. */
212 gain = 1.0;
213 new_step = 1.0 / pitch_overlap;
214 old_step = new_step;
215 new_weight = new_step;
216 old_weight = 1.0 - new_step;
217 for (i = 0; i < pitch_overlap; i++) {
218 amp[i] = fsaturate(old_weight * s->history[PLC_HISTORY_LEN - 1 - i] + new_weight * s->pitchbuf[i]);
219 new_weight += new_step;
220 old_weight -= old_step;
221 if (old_weight < 0.0)
222 old_weight = 0.0;
223 }
224 s->pitch_offset = i;
225 } else {
227 i = 0;
228 }
229 for ( ; gain > 0.0 && i < len; i++) {
230 amp[i] = s->pitchbuf[s->pitch_offset] * gain;
231 gain -= ATTENUATION_INCREMENT;
232 if (++s->pitch_offset >= s->pitch)
233 s->pitch_offset = 0;
234 }
235 for ( ; i < len; i++)
236 amp[i] = 0;
237 s->missing_samples += orig_len;
238 save_history(s, amp, len);
239 return len;
240}
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static void normalise_history(plc_state_t *s)
Definition: plc.c:94
static int __inline__ amdf_pitch(int min_pitch, int max_pitch, int16_t amp[], int len)
Definition: plc.c:108
static int16_t fsaturate(double damp)
Definition: plc.c:62
static void save_history(plc_state_t *s, int16_t *buf, int len)
Definition: plc.c:71
#define ATTENUATION_INCREMENT
Definition: plc.c:58
#define CORRELATION_SPAN
Definition: plc.h:99
#define PLC_HISTORY_LEN
Definition: plc.h:103
#define PLC_PITCH_MIN
Definition: plc.h:93
#define PLC_PITCH_MAX
Definition: plc.h:95
int pitch_offset
Definition: plc.h:110
int pitch
Definition: plc.h:112
int16_t history[PLC_HISTORY_LEN]
Definition: plc.h:116
float pitchbuf[PLC_PITCH_MIN]
Definition: plc.h:114
int missing_samples
Definition: plc.h:108

References amdf_pitch(), ATTENUATION_INCREMENT, CORRELATION_SPAN, fsaturate(), plc_state_t::history, len(), plc_state_t::missing_samples, normalise_history(), plc_state_t::pitch, plc_state_t::pitch_offset, plc_state_t::pitchbuf, PLC_HISTORY_LEN, PLC_PITCH_MAX, PLC_PITCH_MIN, and save_history().

Referenced by adjust_frame_for_plc().

◆ plc_init()

plc_state_t * plc_init ( plc_state_t s)

Process a block of received V.29 modem audio samples.

Process a block of received V.29 modem audio samples.

Parameters
sThe packet loss concealer context.
Returns
A pointer to the he packet loss concealer context.

Definition at line 244 of file plc.c.

245{
246 memset(s, 0, sizeof(*s));
247 return s;
248}

◆ plc_rx()

int plc_rx ( plc_state_t s,
int16_t  amp[],
int  len 
)

Process a block of received audio samples.

Process a block of received audio samples.

Parameters
sThe packet loss concealer context.
ampThe audio sample buffer.
lenThe number of samples in the buffer.
Returns
The number of samples in the buffer.

Definition at line 132 of file plc.c.

133{
134 int i;
135 int pitch_overlap;
136 float old_step;
137 float new_step;
138 float old_weight;
139 float new_weight;
140 float gain;
141
142 if (s->missing_samples) {
143 /* Although we have a real signal, we need to smooth it to fit well
144 with the synthetic signal we used for the previous block */
145
146 /* The start of the real data is overlapped with the next 1/4 cycle
147 of the synthetic data. */
148 pitch_overlap = s->pitch >> 2;
149 if (pitch_overlap > len)
150 pitch_overlap = len;
152 if (gain < 0.0)
153 gain = 0.0;
154 new_step = 1.0/pitch_overlap;
155 old_step = new_step*gain;
156 new_weight = new_step;
157 old_weight = (1.0 - new_step)*gain;
158 for (i = 0; i < pitch_overlap; i++) {
159 amp[i] = fsaturate(old_weight * s->pitchbuf[s->pitch_offset] + new_weight * amp[i]);
160 if (++s->pitch_offset >= s->pitch)
161 s->pitch_offset = 0;
162 new_weight += new_step;
163 old_weight -= old_step;
164 if (old_weight < 0.0)
165 old_weight = 0.0;
166 }
167 s->missing_samples = 0;
168 }
169 save_history(s, amp, len);
170 return len;
171}

References ATTENUATION_INCREMENT, fsaturate(), len(), plc_state_t::missing_samples, plc_state_t::pitch, plc_state_t::pitch_offset, plc_state_t::pitchbuf, and save_history().

Referenced by adjust_frame_for_plc().