2 * RFC 3389 comfort noise generator
3 * Copyright (c) 2012 Martin Storsjo
5 * This file is part of FFmpeg.
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.
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.
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
24 #include "libavutil/common.h"
26 #include "celp_filters.h"
28 #include "libavutil/lfg.h"
30 typedef struct CNGContext
{
31 float *refl_coef
, *target_refl_coef
;
34 int energy
, target_energy
;
41 static av_cold
int cng_decode_close(AVCodecContext
*avctx
)
43 CNGContext
*p
= avctx
->priv_data
;
44 av_freep(&p
->refl_coef
);
45 av_freep(&p
->target_refl_coef
);
46 av_freep(&p
->lpc_coef
);
47 av_freep(&p
->filter_out
);
48 av_freep(&p
->excitation
);
52 static av_cold
int cng_decode_init(AVCodecContext
*avctx
)
54 CNGContext
*p
= avctx
->priv_data
;
56 avctx
->sample_fmt
= AV_SAMPLE_FMT_S16
;
58 avctx
->sample_rate
= 8000;
61 avctx
->frame_size
= 640;
62 p
->refl_coef
= av_mallocz_array(p
->order
, sizeof(*p
->refl_coef
));
63 p
->target_refl_coef
= av_mallocz_array(p
->order
, sizeof(*p
->target_refl_coef
));
64 p
->lpc_coef
= av_mallocz_array(p
->order
, sizeof(*p
->lpc_coef
));
65 p
->filter_out
= av_mallocz_array(avctx
->frame_size
+ p
->order
,
66 sizeof(*p
->filter_out
));
67 p
->excitation
= av_mallocz_array(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
);
74 av_lfg_init(&p
->lfg
, 0);
79 static void make_lpc_coefs(float *lpc
, const float *refl
, int order
)
86 for (m
= 0; m
< order
; m
++) {
88 for (i
= 0; i
< m
; i
++)
89 next
[i
] = cur
[i
] + refl
[m
] * cur
[m
- i
- 1];
90 FFSWAP(float*, next
, cur
);
93 memcpy(lpc
, cur
, sizeof(*lpc
) * order
);
96 static void cng_decode_flush(AVCodecContext
*avctx
)
98 CNGContext
*p
= avctx
->priv_data
;
102 static int cng_decode_frame(AVCodecContext
*avctx
, void *data
,
103 int *got_frame_ptr
, AVPacket
*avpkt
)
105 AVFrame
*frame
= data
;
106 CNGContext
*p
= avctx
->priv_data
;
107 int buf_size
= 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;
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
];
127 p
->energy
= p
->target_energy
;
128 memcpy(p
->refl_coef
, p
->target_refl_coef
, p
->order
* sizeof(*p
->refl_coef
));
131 make_lpc_coefs(p
->lpc_coef
, p
->refl_coef
, p
->order
);
133 for (i
= 0; i
< p
->order
; i
++)
134 e
*= 1.0 - p
->refl_coef
[i
]*p
->refl_coef
[i
];
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
;
141 ff_celp_lp_synthesis_filterf(p
->filter_out
+ p
->order
, p
->lpc_coef
,
142 p
->excitation
, avctx
->frame_size
, p
->order
);
144 frame
->nb_samples
= avctx
->frame_size
;
145 if ((ret
= ff_get_buffer(avctx
, frame
, 0)) < 0)
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
));
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
,