1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
/**
* @file plc.c PLC -- Packet Loss Concealment
*
* Copyright (C) 2010 Creytiv.com
*/
#define SPANDSP_EXPOSE_INTERNAL_STRUCTURES
#include <spandsp.h>
#include <re.h>
#include <baresip.h>
/**
* @defgroup plc plc
*
* Packet Loss Concealment (PLC) audio-filter using spandsp
*
*/
struct plc_st {
struct aufilt_dec_st af; /* base class */
plc_state_t plc;
size_t sampc;
};
static void destructor(void *arg)
{
struct plc_st *st = arg;
list_unlink(&st->af.le);
}
static int update(struct aufilt_dec_st **stp, void **ctx,
const struct aufilt *af, struct aufilt_prm *prm)
{
struct plc_st *st;
int err = 0;
(void)ctx;
(void)af;
if (!stp || !prm)
return EINVAL;
if (*stp)
return 0;
/* XXX: add support for stereo PLC */
if (prm->ch != 1) {
warning("plc: only mono supported (ch=%u)\n", prm->ch);
return ENOSYS;
}
st = mem_zalloc(sizeof(*st), destructor);
if (!st)
return ENOMEM;
if (!plc_init(&st->plc)) {
err = ENOMEM;
goto out;
}
st->sampc = prm->srate * prm->ch * prm->ptime / 1000;
out:
if (err)
mem_deref(st);
else
*stp = (struct aufilt_dec_st *)st;
return err;
}
/*
* PLC is only valid for Decoding (RX)
*
* NOTE: sampc == 0 , means Packet loss
*/
static int decode(struct aufilt_dec_st *st, int16_t *sampv, size_t *sampc)
{
struct plc_st *plc = (struct plc_st *)st;
if (*sampc)
plc_rx(&plc->plc, sampv, (int)*sampc);
else
*sampc = plc_fillin(&plc->plc, sampv, (int)plc->sampc);
return 0;
}
static struct aufilt plc = {
LE_INIT, "plc", NULL, NULL, update, decode
};
static int module_init(void)
{
aufilt_register(baresip_aufiltl(), &plc);
return 0;
}
static int module_close(void)
{
aufilt_unregister(&plc);
return 0;
}
EXPORT_SYM const struct mod_export DECL_EXPORTS(plc) = {
"plc",
"filter",
module_init,
module_close
};
|