Asterisk - The Open Source Telephony Project GIT-master-a358458
Macros | Functions | Variables
plc.c File Reference

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

#include "asterisk.h"
#include <math.h>
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/plc.h"
Include dependency graph for plc.c:

Go to the source code of this file.

Macros

#define ATTENUATION_INCREMENT   0.0025 /* Attenuation per sample */
 
#define FALSE   0
 
#define INT16_MAX   (32767)
 
#define INT16_MIN   (-32767-1)
 
#define ms_to_samples(t)   (((t)*DEFAULT_SAMPLE_RATE)/1000)
 
#define TRUE   (!FALSE)
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static int __inline__ amdf_pitch (int min_pitch, int max_pitch, int16_t amp[], int len)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int16_t fsaturate (double damp)
 
static int load_module (void)
 
static void normalise_history (plc_state_t *s)
 
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...
 
static int reload_module (void)
 
static void save_history (plc_state_t *s, int16_t *buf, int len)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "PLC" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload_module, .load_pri = AST_MODPRI_CORE, .requires = "extconfig", }
 
static const struct ast_module_infoast_module_info = &__mod_info
 

Detailed Description

SpanDSP - a series of DSP components for telephony.

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

Definition in file plc.c.

Macro Definition Documentation

◆ ATTENUATION_INCREMENT

#define ATTENUATION_INCREMENT   0.0025 /* Attenuation per sample */

Definition at line 58 of file plc.c.

◆ FALSE

#define FALSE   0

Definition at line 46 of file plc.c.

◆ INT16_MAX

#define INT16_MAX   (32767)

Definition at line 53 of file plc.c.

◆ INT16_MIN

#define INT16_MIN   (-32767-1)

Definition at line 54 of file plc.c.

◆ ms_to_samples

#define ms_to_samples (   t)    (((t)*DEFAULT_SAMPLE_RATE)/1000)

Definition at line 60 of file plc.c.

◆ TRUE

#define TRUE   (!FALSE)

Definition at line 49 of file plc.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 300 of file plc.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 300 of file plc.c.

◆ amdf_pitch()

static int __inline__ amdf_pitch ( int  min_pitch,
int  max_pitch,
int16_t  amp[],
int  len 
)
static

Definition at line 108 of file plc.c.

109{
110 int i;
111 int j;
112 int acc;
113 int min_acc;
114 int pitch;
115
116 pitch = min_pitch;
117 min_acc = INT_MAX;
118 for (i = max_pitch; i <= min_pitch; i++) {
119 acc = 0;
120 for (j = 0; j < len; j++)
121 acc += abs(amp[i + j] - amp[j]);
122 if (acc < min_acc) {
123 min_acc = acc;
124 pitch = i;
125 }
126 }
127 return pitch;
128}
#define abs(x)
Definition: f2c.h:195
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)

References abs, and len().

Referenced by plc_fillin().

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 300 of file plc.c.

◆ fsaturate()

static int16_t fsaturate ( double  damp)
inlinestatic

Definition at line 62 of file plc.c.

63{
64 if (damp > 32767.0)
65 return INT16_MAX;
66 if (damp < -32768.0)
67 return INT16_MIN;
68 return (int16_t) rint(damp);
69}
short int16_t
Definition: db.h:59
#define INT16_MAX
Definition: plc.c:53
#define INT16_MIN
Definition: plc.c:54

References INT16_MAX, and INT16_MIN.

Referenced by plc_fillin(), and plc_rx().

◆ load_module()

static int load_module ( void  )
static

Definition at line 281 of file plc.c.

282{
284
286}
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
static int reload_module(void)
Definition: plc.c:252

References AST_MODULE_LOAD_SUCCESS, and reload_module().

◆ normalise_history()

static void normalise_history ( plc_state_t s)
static

Definition at line 94 of file plc.c.

95{
97
98 if (s->buf_ptr == 0)
99 return;
100 memcpy(tmp, s->history, sizeof(int16_t)*s->buf_ptr);
101 memmove(s->history, s->history + s->buf_ptr, sizeof(int16_t) * (PLC_HISTORY_LEN - s->buf_ptr));
102 memcpy(s->history + PLC_HISTORY_LEN - s->buf_ptr, tmp, sizeof(int16_t) * s->buf_ptr);
103 s->buf_ptr = 0;
104}
static int tmp()
Definition: bt_open.c:389
#define PLC_HISTORY_LEN
Definition: plc.h:103
int16_t history[PLC_HISTORY_LEN]
Definition: plc.h:116
int buf_ptr
Definition: plc.h:118

References plc_state_t::buf_ptr, plc_state_t::history, PLC_HISTORY_LEN, and tmp().

Referenced by plc_fillin().

◆ 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 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_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
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().

◆ reload_module()

static int reload_module ( void  )
static

Definition at line 252 of file plc.c.

253{
254 struct ast_variable *var;
255 struct ast_flags config_flags = { 0 };
256 struct ast_config *cfg = ast_config_load("codecs.conf", config_flags);
257
259 return 0;
260 }
261
262 for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
263 if (!strcasecmp(var->name, "genericplc")) {
265 } else if (!strcasecmp(var->name, "genericplc_on_equal_codecs")) {
267 }
268 }
270
271 /*
272 * Force on_equal_codecs to false if generic_plc is false.
273 */
274 if (!ast_opt_generic_plc) {
276 }
277
278 return 0;
279}
#define var
Definition: ast_expr2f.c:605
struct ast_flags ast_options
Definition: options.c:61
@ AST_OPT_FLAG_GENERIC_PLC
Definition: options.h:100
@ AST_OPT_FLAG_GENERIC_PLC_ON_EQUAL_CODECS
Definition: options.h:102
#define ast_config_load(filename, flags)
Load a config file.
#define CONFIG_STATUS_FILEMISSING
#define CONFIG_STATUS_FILEUNCHANGED
#define CONFIG_STATUS_FILEINVALID
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: extconf.c:1289
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1215
#define ast_opt_generic_plc
Definition: options.h:134
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
Definition: utils.c:2199
Structure used to handle boolean flags.
Definition: utils.h:199
Structure for variables, used for configurations and for channel variables.
#define ast_set2_flag(p, value, flag)
Definition: utils.h:94

References ast_config_destroy(), ast_config_load, AST_OPT_FLAG_GENERIC_PLC, AST_OPT_FLAG_GENERIC_PLC_ON_EQUAL_CODECS, ast_opt_generic_plc, ast_options, ast_set2_flag, ast_true(), ast_variable_browse(), CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, CONFIG_STATUS_FILEUNCHANGED, and var.

Referenced by load_module().

◆ save_history()

static void save_history ( plc_state_t s,
int16_t buf,
int  len 
)
static

Definition at line 71 of file plc.c.

72{
73 if (len >= PLC_HISTORY_LEN) {
74 /* Just keep the last part of the new data, starting at the beginning of the buffer */
75 memcpy(s->history, buf + len - PLC_HISTORY_LEN, sizeof(int16_t) * PLC_HISTORY_LEN);
76 s->buf_ptr = 0;
77 return;
78 }
79 if (s->buf_ptr + len > PLC_HISTORY_LEN) {
80 /* Wraps around - must break into two sections */
81 memcpy(s->history + s->buf_ptr, buf, sizeof(int16_t) * (PLC_HISTORY_LEN - s->buf_ptr));
82 len -= (PLC_HISTORY_LEN - s->buf_ptr);
83 memcpy(s->history, buf + (PLC_HISTORY_LEN - s->buf_ptr), sizeof(int16_t)*len);
84 s->buf_ptr = len;
85 return;
86 }
87 /* Can use just one section */
88 memcpy(s->history + s->buf_ptr, buf, sizeof(int16_t)*len);
89 s->buf_ptr += len;
90}
char buf[BUFSIZE]
Definition: eagi_proxy.c:66

References buf, plc_state_t::buf_ptr, plc_state_t::history, len(), and PLC_HISTORY_LEN.

Referenced by plc_fillin(), and plc_rx().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 288 of file plc.c.

289{
290 return 0;
291}

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "PLC" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload_module, .load_pri = AST_MODPRI_CORE, .requires = "extconfig", }
static

Definition at line 300 of file plc.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 300 of file plc.c.