FFmpeg
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
Examples
File List
Globals
•
All
Data Structures
Namespaces
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
float
*
refl_coef
, *
target_refl_coef
;
32
float
*
lpc_coef
;
33
int
order
;
34
int
energy
,
target_energy
;
35
int
inited
;
36
float
*
filter_out
;
37
float
*
excitation
;
38
AVLFG
lfg
;
39
}
CNGContext
;
40
41
static
av_cold
int
cng_decode_close
(
AVCodecContext
*avctx)
42
{
43
CNGContext
*p = avctx->
priv_data
;
44
av_free
(p->
refl_coef
);
45
av_free
(p->
target_refl_coef
);
46
av_free
(p->
lpc_coef
);
47
av_free
(p->
filter_out
);
48
av_free
(p->
excitation
);
49
return
0;
50
}
51
52
static
av_cold
int
cng_decode_init
(
AVCodecContext
*avctx)
53
{
54
CNGContext
*p = avctx->
priv_data
;
55
56
avctx->
sample_fmt
=
AV_SAMPLE_FMT_S16
;
57
avctx->
channels
= 1;
58
avctx->
sample_rate
= 8000;
59
60
p->
order
= 12;
61
avctx->
frame_size
= 640;
62
p->
refl_coef
=
av_mallocz
(p->
order
*
sizeof
(*p->
refl_coef
));
63
p->
target_refl_coef
=
av_mallocz
(p->
order
*
sizeof
(*p->
target_refl_coef
));
64
p->
lpc_coef
=
av_mallocz
(p->
order
*
sizeof
(*p->
lpc_coef
));
65
p->
filter_out
=
av_mallocz
((avctx->
frame_size
+ p->
order
) *
66
sizeof
(*p->
filter_out
));
67
p->
excitation
=
av_mallocz
(avctx->
frame_size
*
sizeof
(*p->
excitation
));
68
if
(!p->
refl_coef
|| !p->
target_refl_coef
|| !p->
lpc_coef
||
69
!p->
filter_out
|| !p->
excitation
) {
70
cng_decode_close
(avctx);
71
return
AVERROR
(ENOMEM);
72
}
73
74
av_lfg_init
(&p->
lfg
, 0);
75
76
return
0;
77
}
78
79
static
void
make_lpc_coefs
(
float
*lpc,
const
float
*refl,
int
order)
80
{
81
float
buf
[100];
82
float
*next, *cur;
83
int
m
, i;
84
next =
buf
;
85
cur = lpc;
86
for
(m = 0; m < order; m++) {
87
next[
m
] = refl[
m
];
88
for
(i = 0; i <
m
; i++)
89
next[i] = cur[i] + refl[m] * cur[m - i - 1];
90
FFSWAP
(
float
*, next, cur);
91
}
92
if
(cur != lpc)
93
memcpy(lpc, cur,
sizeof
(*lpc) * order);
94
}
95
96
static
void
cng_decode_flush
(
AVCodecContext
*avctx)
97
{
98
CNGContext
*p = avctx->
priv_data
;
99
p->
inited
= 0;
100
}
101
102
static
int
cng_decode_frame
(
AVCodecContext
*avctx,
void
*
data
,
103
int
*got_frame_ptr,
AVPacket
*avpkt)
104
{
105
AVFrame
*
frame
=
data
;
106
CNGContext
*p = avctx->
priv_data
;
107
int
buf_size = avpkt->
size
;
108
int
ret
, i;
109
int16_t *buf_out;
110
float
e = 1.0;
111
float
scaling;
112
113
if
(avpkt->
size
) {
114
int
dbov = -avpkt->
data
[0];
115
p->
target_energy
= 1081109975 * pow(10, dbov / 10.0) * 0.75;
116
memset(p->
target_refl_coef
, 0, p->
order
*
sizeof
(*p->
target_refl_coef
));
117
for
(i = 0; i <
FFMIN
(avpkt->
size
- 1, p->
order
); i++) {
118
p->
target_refl_coef
[i] = (avpkt->
data
[1 + i] - 127) / 128.0;
119
}
120
}
121
122
if
(p->
inited
) {
123
p->
energy
= p->
energy
/ 2 + p->
target_energy
/ 2;
124
for
(i = 0; i < p->
order
; i++)
125
p->
refl_coef
[i] = 0.6 *p->
refl_coef
[i] + 0.4 * p->
target_refl_coef
[i];
126
}
else
{
127
p->
energy
= p->
target_energy
;
128
memcpy(p->
refl_coef
, p->
target_refl_coef
, p->
order
*
sizeof
(*p->
refl_coef
));
129
p->
inited
= 1;
130
}
131
make_lpc_coefs
(p->
lpc_coef
, p->
refl_coef
, p->
order
);
132
133
for
(i = 0; i < p->
order
; i++)
134
e *= 1.0 - p->
refl_coef
[i]*p->
refl_coef
[i];
135
136
scaling = sqrt(e * p->
energy
/ 1081109975);
137
for
(i = 0; i < avctx->
frame_size
; i++) {
138
int
r
= (
av_lfg_get
(&p->
lfg
) & 0xffff) - 0x8000;
139
p->
excitation
[i] = scaling *
r
;
140
}
141
ff_celp_lp_synthesis_filterf
(p->
filter_out
+ p->
order
, p->
lpc_coef
,
142
p->
excitation
, avctx->
frame_size
, p->
order
);
143
144
frame->
nb_samples
= avctx->
frame_size
;
145
if
((ret =
ff_get_buffer
(avctx, frame, 0)) < 0)
146
return
ret
;
147
buf_out = (int16_t *)frame->
data
[0];
148
for
(i = 0; i < avctx->
frame_size
; i++)
149
buf_out[i] = p->
filter_out
[i + p->
order
];
150
memcpy(p->
filter_out
, p->
filter_out
+ avctx->
frame_size
,
151
p->
order
*
sizeof
(*p->
filter_out
));
152
153
*got_frame_ptr = 1;
154
155
return
buf_size;
156
}
157
158
AVCodec
ff_comfortnoise_decoder
= {
159
.
name
=
"comfortnoise"
,
160
.long_name =
NULL_IF_CONFIG_SMALL
(
"RFC 3389 comfort noise generator"
),
161
.type =
AVMEDIA_TYPE_AUDIO
,
162
.id =
AV_CODEC_ID_COMFORT_NOISE
,
163
.priv_data_size =
sizeof
(
CNGContext
),
164
.
init
=
cng_decode_init
,
165
.
decode
=
cng_decode_frame
,
166
.
flush
=
cng_decode_flush
,
167
.
close
=
cng_decode_close
,
168
.
sample_fmts
= (
const
enum
AVSampleFormat
[]){
AV_SAMPLE_FMT_S16
,
169
AV_SAMPLE_FMT_NONE
},
170
.capabilities =
CODEC_CAP_DELAY
|
CODEC_CAP_DR1
,
171
};
Generated on Sun Mar 23 2014 23:49:52 for FFmpeg by
1.8.2