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
|
/**
* @file opus/decode.c Opus Decode
*
* Copyright (C) 2010 Creytiv.com
*/
#include <re.h>
#include <baresip.h>
#include <opus/opus.h>
#include "opus.h"
struct audec_state {
OpusDecoder *dec;
unsigned ch;
};
static void destructor(void *arg)
{
struct audec_state *ads = arg;
if (ads->dec)
opus_decoder_destroy(ads->dec);
}
int opus_decode_update(struct audec_state **adsp, const struct aucodec *ac,
const char *fmtp)
{
struct audec_state *ads;
int opuserr, err = 0;
(void)fmtp;
if (!adsp || !ac || !ac->ch)
return EINVAL;
ads = *adsp;
if (ads)
return 0;
ads = mem_zalloc(sizeof(*ads), destructor);
if (!ads)
return ENOMEM;
ads->ch = ac->ch;
ads->dec = opus_decoder_create(ac->srate, ac->ch, &opuserr);
if (!ads->dec) {
warning("opus: decoder create: %s\n", opus_strerror(opuserr));
err = ENOMEM;
goto out;
}
out:
if (err)
mem_deref(ads);
else
*adsp = ads;
return err;
}
int opus_decode_frm(struct audec_state *ads, int16_t *sampv, size_t *sampc,
const uint8_t *buf, size_t len)
{
int n;
if (!ads || !sampv || !sampc || !buf)
return EINVAL;
n = opus_decode(ads->dec, buf, (opus_int32)len,
sampv, (int)(*sampc/ads->ch), 0);
if (n < 0) {
warning("opus: decode error: %s\n", opus_strerror(n));
return EPROTO;
}
*sampc = n * ads->ch;
return 0;
}
int opus_decode_pkloss(struct audec_state *ads, int16_t *sampv, size_t *sampc)
{
int n;
if (!ads || !sampv || !sampc)
return EINVAL;
n = opus_decode(ads->dec, NULL, 0, sampv, (int)(*sampc/ads->ch), 0);
if (n < 0)
return EPROTO;
*sampc = n * ads->ch;
return 0;
}
|