Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
libavcodec
psymodel.c
Go to the documentation of this file.
1
/*
2
* audio encoder psychoacoustic model
3
* Copyright (C) 2008 Konstantin Shishkov
4
*
5
* This file is part of Libav.
6
*
7
* Libav 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
* Libav 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 Libav; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
*/
21
22
#include "
avcodec.h
"
23
#include "
psymodel.h
"
24
#include "
iirfilter.h
"
25
26
extern
const
FFPsyModel
ff_aac_psy_model
;
27
28
av_cold
int
ff_psy_init
(
FFPsyContext
*ctx,
AVCodecContext
*avctx,
int
num_lens,
29
const
uint8_t **bands,
const
int
* num_bands,
30
int
num_groups,
const
uint8_t *group_map)
31
{
32
int
i, j, k = 0;
33
34
ctx->
avctx
= avctx;
35
ctx->
ch
=
av_mallocz
(
sizeof
(ctx->
ch
[0]) * avctx->
channels
* 2);
36
ctx->
group
=
av_mallocz
(
sizeof
(ctx->
group
[0]) * num_groups);
37
ctx->
bands
=
av_malloc
(
sizeof
(ctx->
bands
[0]) * num_lens);
38
ctx->
num_bands
=
av_malloc
(
sizeof
(ctx->
num_bands
[0]) * num_lens);
39
memcpy(ctx->
bands
, bands,
sizeof
(ctx->
bands
[0]) * num_lens);
40
memcpy(ctx->
num_bands
, num_bands,
sizeof
(ctx->
num_bands
[0]) * num_lens);
41
42
/* assign channels to groups (with virtual channels for coupling) */
43
for
(i = 0; i < num_groups; i++) {
44
/* NOTE: Add 1 to handle the AAC chan_config without modification.
45
* This has the side effect of allowing an array of 0s to map
46
* to one channel per group.
47
*/
48
ctx->
group
[i].
num_ch
= group_map[i] + 1;
49
for
(j = 0; j < ctx->
group
[i].
num_ch
* 2; j++)
50
ctx->
group
[i].
ch
[j] = &ctx->
ch
[k++];
51
}
52
53
switch
(ctx->
avctx
->
codec_id
) {
54
case
CODEC_ID_AAC
:
55
ctx->
model
= &
ff_aac_psy_model
;
56
break
;
57
}
58
if
(ctx->
model
->
init
)
59
return
ctx->
model
->
init
(ctx);
60
return
0;
61
}
62
63
FFPsyChannelGroup
*
ff_psy_find_group
(
FFPsyContext
*ctx,
int
channel)
64
{
65
int
i = 0, ch = 0;
66
67
while
(ch <= channel)
68
ch += ctx->
group
[i++].
num_ch
;
69
70
return
&ctx->
group
[i-1];
71
}
72
73
av_cold
void
ff_psy_end
(
FFPsyContext
*ctx)
74
{
75
if
(ctx->
model
->
end
)
76
ctx->
model
->
end
(ctx);
77
av_freep
(&ctx->
bands
);
78
av_freep
(&ctx->
num_bands
);
79
av_freep
(&ctx->
group
);
80
av_freep
(&ctx->
ch
);
81
}
82
83
typedef
struct
FFPsyPreprocessContext
{
84
AVCodecContext
*
avctx
;
85
float
stereo_att
;
86
struct
FFIIRFilterCoeffs
*
fcoeffs
;
87
struct
FFIIRFilterState
**
fstate
;
88
}
FFPsyPreprocessContext
;
89
90
#define FILT_ORDER 4
91
92
av_cold
struct
FFPsyPreprocessContext
*
ff_psy_preprocess_init
(
AVCodecContext
*
avctx
)
93
{
94
FFPsyPreprocessContext
*ctx;
95
int
i;
96
float
cutoff_coeff = 0;
97
ctx =
av_mallocz
(
sizeof
(
FFPsyPreprocessContext
));
98
ctx->
avctx
=
avctx
;
99
100
if
(avctx->
cutoff
> 0)
101
cutoff_coeff = 2.0 * avctx->
cutoff
/ avctx->
sample_rate
;
102
103
if
(cutoff_coeff)
104
ctx->
fcoeffs
=
ff_iir_filter_init_coeffs
(avctx,
FF_FILTER_TYPE_BUTTERWORTH
,
105
FF_FILTER_MODE_LOWPASS
,
FILT_ORDER
,
106
cutoff_coeff, 0.0, 0.0);
107
if
(ctx->
fcoeffs
) {
108
ctx->
fstate
=
av_mallocz
(
sizeof
(ctx->
fstate
[0]) * avctx->
channels
);
109
for
(i = 0; i < avctx->
channels
; i++)
110
ctx->
fstate
[i] =
ff_iir_filter_init_state
(
FILT_ORDER
);
111
}
112
return
ctx;
113
}
114
115
void
ff_psy_preprocess
(
struct
FFPsyPreprocessContext
*ctx,
116
const
int16_t *audio, int16_t *dest,
117
int
tag
,
int
channels)
118
{
119
int
ch, i;
120
if
(ctx->
fstate
) {
121
for
(ch = 0; ch < channels; ch++)
122
ff_iir_filter
(ctx->
fcoeffs
, ctx->
fstate
[tag+ch], ctx->
avctx
->
frame_size
,
123
audio + ch, ctx->
avctx
->
channels
,
124
dest + ch, ctx->
avctx
->
channels
);
125
}
else
{
126
for
(ch = 0; ch < channels; ch++)
127
for
(i = 0; i < ctx->
avctx
->
frame_size
; i++)
128
dest[i*ctx->
avctx
->
channels
+ ch] = audio[i*ctx->
avctx
->
channels
+ ch];
129
}
130
}
131
132
av_cold
void
ff_psy_preprocess_end
(
struct
FFPsyPreprocessContext
*ctx)
133
{
134
int
i;
135
ff_iir_filter_free_coeffs
(ctx->
fcoeffs
);
136
if
(ctx->
fstate
)
137
for
(i = 0; i < ctx->
avctx
->
channels
; i++)
138
ff_iir_filter_free_state
(ctx->
fstate
[i]);
139
av_freep
(&ctx->
fstate
);
140
av_free
(ctx);
141
}
142