FFmpeg
Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
•
All
Data Structures
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
libavcodec
cngdec.c
Go to the documentation of this file.
1
/*
2
* RFC 3389 comfort noise generator
3
* Copyright (c) 2012 Martin Storsjo
4
*
5
* This file is part of FFmpeg.
6
*
7
* FFmpeg is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 2.1 of the License, or (at your option) any later version.
11
*
12
* FFmpeg is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
16
*
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with FFmpeg; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
*/
21
22
#include <
math.h
>
23
24
#include "
libavutil/common.h
"
25
#include "
avcodec.h
"
26
#include "
celp_filters.h
"
27
#include "
internal.h
"
28
#include "
libavutil/lfg.h
"
29
30
typedef
struct
CNGContext
{
31
AVFrame
avframe
;
32
float
*
refl_coef
, *
target_refl_coef
;
33
float
*
lpc_coef
;
34
int
order
;
35
int
energy
,
target_energy
;
36
int
inited
;
37
float
*
filter_out
;
38
float
*
excitation
;
39
AVLFG
lfg
;
40
}
CNGContext
;
41
42
static
av_cold
int
cng_decode_close
(
AVCodecContext
*avctx)
43
{
44
CNGContext
*p = avctx->
priv_data
;
45
av_free
(p->
refl_coef
);
46
av_free
(p->
target_refl_coef
);
47
av_free
(p->
lpc_coef
);
48
av_free
(p->
filter_out
);
49
av_free
(p->
excitation
);
50
return
0;
51
}
52
53
static
av_cold
int
cng_decode_init
(
AVCodecContext
*avctx)
54
{
55
CNGContext
*p = avctx->
priv_data
;
56
57
avctx->
sample_fmt
=
AV_SAMPLE_FMT_S16
;
58
avctx->
channels
= 1;
59
avctx->
sample_rate
= 8000;
60
61
avcodec_get_frame_defaults
(&p->
avframe
);
62
avctx->
coded_frame
= &p->
avframe
;
63
p->
order
= 12;
64
avctx->
frame_size
= 640;
65
p->
refl_coef
=
av_mallocz
(p->
order
*
sizeof
(*p->
refl_coef
));
66
p->
target_refl_coef
=
av_mallocz
(p->
order
*
sizeof
(*p->
target_refl_coef
));
67
p->
lpc_coef
=
av_mallocz
(p->
order
*
sizeof
(*p->
lpc_coef
));
68
p->
filter_out
=
av_mallocz
((avctx->
frame_size
+ p->
order
) *
69
sizeof
(*p->
filter_out
));
70
p->
excitation
=
av_mallocz
(avctx->
frame_size
*
sizeof
(*p->
excitation
));
71
if
(!p->
refl_coef
|| !p->
target_refl_coef
|| !p->
lpc_coef
||
72
!p->
filter_out
|| !p->
excitation
) {
73
cng_decode_close
(avctx);
74
return
AVERROR
(ENOMEM);
75
}
76
77
av_lfg_init
(&p->
lfg
, 0);
78
79
return
0;
80
}
81
82
static
void
make_lpc_coefs
(
float
*lpc,
const
float
*refl,
int
order)
83
{
84
float
buf[100];
85
float
*next, *cur;
86
int
m
, i;
87
next = buf;
88
cur = lpc;
89
for
(m = 0; m < order; m++) {
90
next[
m
] = refl[
m
];
91
for
(i = 0; i <
m
; i++)
92
next[i] = cur[i] + refl[m] * cur[m - i - 1];
93
FFSWAP
(
float
*, next, cur);
94
}
95
if
(cur != lpc)
96
memcpy(lpc, cur,
sizeof
(*lpc) * order);
97
}
98
99
static
void
cng_decode_flush
(
AVCodecContext
*avctx)
100
{
101
CNGContext
*p = avctx->
priv_data
;
102
p->
inited
= 0;
103
}
104
105
static
int
cng_decode_frame
(
AVCodecContext
*avctx,
void
*
data
,
106
int
*got_frame_ptr,
AVPacket
*avpkt)
107
{
108
109
CNGContext
*p = avctx->
priv_data
;
110
int
buf_size = avpkt->
size
;
111
int
ret, i;
112
int16_t *buf_out;
113
float
e = 1.0;
114
float
scaling;
115
116
if
(avpkt->
size
) {
117
int
dbov = -avpkt->
data
[0];
118
p->
target_energy
= 1081109975 * pow(10, dbov / 10.0) * 0.75;
119
memset(p->
target_refl_coef
, 0, p->
order
*
sizeof
(*p->
target_refl_coef
));
120
for
(i = 0; i <
FFMIN
(avpkt->
size
- 1, p->
order
); i++) {
121
p->
target_refl_coef
[i] = (avpkt->
data
[1 + i] - 127) / 128.0;
122
}
123
}
124
125
if
(p->
inited
) {
126
p->
energy
= p->
energy
/ 2 + p->
target_energy
/ 2;
127
for
(i = 0; i < p->
order
; i++)
128
p->
refl_coef
[i] = 0.6 *p->
refl_coef
[i] + 0.4 * p->
target_refl_coef
[i];
129
}
else
{
130
p->
energy
= p->
target_energy
;
131
memcpy(p->
refl_coef
, p->
target_refl_coef
, p->
order
*
sizeof
(*p->
refl_coef
));
132
p->
inited
= 1;
133
}
134
make_lpc_coefs
(p->
lpc_coef
, p->
refl_coef
, p->
order
);
135
136
for
(i = 0; i < p->
order
; i++)
137
e *= 1.0 - p->
refl_coef
[i]*p->
refl_coef
[i];
138
139
scaling = sqrt(e * p->
energy
/ 1081109975);
140
for
(i = 0; i < avctx->
frame_size
; i++) {
141
int
r
= (
av_lfg_get
(&p->
lfg
) & 0xffff) - 0x8000;
142
p->
excitation
[i] = scaling *
r
;
143
}
144
ff_celp_lp_synthesis_filterf
(p->
filter_out
+ p->
order
, p->
lpc_coef
,
145
p->
excitation
, avctx->
frame_size
, p->
order
);
146
147
p->
avframe
.
nb_samples
= avctx->
frame_size
;
148
if
((ret =
ff_get_buffer
(avctx, &p->
avframe
)) < 0) {
149
av_log
(avctx,
AV_LOG_ERROR
,
"get_buffer() failed\n"
);
150
return
ret;
151
}
152
buf_out = (int16_t *)p->
avframe
.
data
[0];
153
for
(i = 0; i < avctx->
frame_size
; i++)
154
buf_out[i] = p->
filter_out
[i + p->
order
];
155
memcpy(p->
filter_out
, p->
filter_out
+ avctx->
frame_size
,
156
p->
order
*
sizeof
(*p->
filter_out
));
157
158
*got_frame_ptr = 1;
159
*(
AVFrame
*)data = p->
avframe
;
160
161
return
buf_size;
162
}
163
164
AVCodec
ff_comfortnoise_decoder
= {
165
.
name
=
"comfortnoise"
,
166
.type =
AVMEDIA_TYPE_AUDIO
,
167
.id =
AV_CODEC_ID_COMFORT_NOISE
,
168
.priv_data_size =
sizeof
(
CNGContext
),
169
.
init
=
cng_decode_init
,
170
.
decode
=
cng_decode_frame
,
171
.
flush
=
cng_decode_flush
,
172
.
close
=
cng_decode_close
,
173
.long_name =
NULL_IF_CONFIG_SMALL
(
"RFC 3389 comfort noise generator"
),
174
.sample_fmts = (
const
enum
AVSampleFormat
[]){
AV_SAMPLE_FMT_S16
,
175
AV_SAMPLE_FMT_NONE
},
176
.capabilities =
CODEC_CAP_DELAY
|
CODEC_CAP_DR1
,
177
};
Generated on Sat May 25 2013 03:58:32 for FFmpeg by
1.8.2