Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
libavcodec
nellymoserdec.c
Go to the documentation of this file.
1
/*
2
* NellyMoser audio decoder
3
* Copyright (c) 2007 a840bda5870ba11f19698ff6eb9581dfb0f95fa5,
4
* 539459aeb7d425140b62a3ec7dbf6dc8e408a306, and
5
* 520e17cd55896441042b14df2566a6eb610ed444
6
* Copyright (c) 2007 Loic Minier <lool at dooz.org>
7
* Benjamin Larsson
8
*
9
* Permission is hereby granted, free of charge, to any person obtaining a
10
* copy of this software and associated documentation files (the "Software"),
11
* to deal in the Software without restriction, including without limitation
12
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
13
* and/or sell copies of the Software, and to permit persons to whom the
14
* Software is furnished to do so, subject to the following conditions:
15
*
16
* The above copyright notice and this permission notice shall be included in
17
* all copies or substantial portions of the Software.
18
*
19
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25
* DEALINGS IN THE SOFTWARE.
26
*/
27
34
#include "
nellymoser.h
"
35
#include "
libavutil/lfg.h
"
36
#include "
libavutil/random_seed.h
"
37
#include "
libavutil/audioconvert.h
"
38
#include "
avcodec.h
"
39
#include "
internal.h
"
40
#include "
dsputil.h
"
41
#include "
fft.h
"
42
#include "
fmtconvert.h
"
43
#include "
sinewin.h
"
44
45
#define BITSTREAM_READER_LE
46
#include "
get_bits.h
"
47
48
49
typedef
struct
NellyMoserDecodeContext
{
50
AVCodecContext
*
avctx
;
51
AVFrame
frame
;
52
float
*
float_buf
;
53
DECLARE_ALIGNED
(16,
float
,
state
)[
NELLY_BUF_LEN
];
54
AVLFG
random_state
;
55
GetBitContext
gb
;
56
float
scale_bias
;
57
DSPContext
dsp
;
58
FFTContext
imdct_ctx
;
59
FmtConvertContext
fmt_conv
;
60
DECLARE_ALIGNED
(32,
float
,
imdct_out
)[
NELLY_BUF_LEN
* 2];
61
}
NellyMoserDecodeContext
;
62
63
static
void
nelly_decode_block
(
NellyMoserDecodeContext
*s,
64
const
unsigned
char
block
[
NELLY_BLOCK_LEN
],
65
float
audio[
NELLY_SAMPLES
])
66
{
67
int
i,j;
68
float
buf[
NELLY_FILL_LEN
], pows[
NELLY_FILL_LEN
];
69
float
*aptr, *bptr, *pptr, val, pval;
70
int
bits
[
NELLY_BUF_LEN
];
71
unsigned
char
v
;
72
73
init_get_bits
(&s->
gb
,
block
, NELLY_BLOCK_LEN * 8);
74
75
bptr = buf;
76
pptr = pows;
77
val =
ff_nelly_init_table
[
get_bits
(&s->
gb
, 6)];
78
for
(i=0 ; i<
NELLY_BANDS
; i++) {
79
if
(i > 0)
80
val +=
ff_nelly_delta_table
[
get_bits
(&s->
gb
, 5)];
81
pval = -pow(2, val/2048) * s->
scale_bias
;
82
for
(j = 0; j <
ff_nelly_band_sizes_table
[i]; j++) {
83
*bptr++ = val;
84
*pptr++ = pval;
85
}
86
87
}
88
89
ff_nelly_get_sample_bits
(buf, bits);
90
91
for
(i = 0; i < 2; i++) {
92
aptr = audio + i *
NELLY_BUF_LEN
;
93
94
init_get_bits
(&s->
gb
,
block
, NELLY_BLOCK_LEN * 8);
95
skip_bits_long
(&s->
gb
,
NELLY_HEADER_BITS
+ i*
NELLY_DETAIL_BITS
);
96
97
for
(j = 0; j <
NELLY_FILL_LEN
; j++) {
98
if
(bits[j] <= 0) {
99
aptr[j] =
M_SQRT1_2
*pows[j];
100
if
(
av_lfg_get
(&s->
random_state
) & 1)
101
aptr[j] *= -1.0;
102
}
else
{
103
v =
get_bits
(&s->
gb
, bits[j]);
104
aptr[j] =
ff_nelly_dequantization_table
[(1<<bits[j])-1+v]*pows[j];
105
}
106
}
107
memset(&aptr[NELLY_FILL_LEN], 0,
108
(NELLY_BUF_LEN - NELLY_FILL_LEN) *
sizeof
(
float
));
109
110
s->
imdct_ctx
.
imdct_calc
(&s->
imdct_ctx
, s->
imdct_out
, aptr);
111
/* XXX: overlapping and windowing should be part of a more
112
generic imdct function */
113
s->
dsp
.
vector_fmul_reverse
(s->
state
, s->
state
, ff_sine_128, NELLY_BUF_LEN);
114
s->
dsp
.
vector_fmul_add
(aptr, s->
imdct_out
, ff_sine_128, s->
state
, NELLY_BUF_LEN);
115
memcpy(s->
state
, s->
imdct_out
+ NELLY_BUF_LEN,
sizeof
(
float
)*NELLY_BUF_LEN);
116
}
117
}
118
119
static
av_cold
int
decode_init
(
AVCodecContext
* avctx) {
120
NellyMoserDecodeContext
*s = avctx->
priv_data
;
121
122
s->
avctx
= avctx;
123
av_lfg_init
(&s->
random_state
, 0);
124
ff_mdct_init
(&s->
imdct_ctx
, 8, 1, 1.0);
125
126
dsputil_init
(&s->
dsp
, avctx);
127
128
if
(avctx->
request_sample_fmt
==
AV_SAMPLE_FMT_FLT
) {
129
s->
scale_bias
= 1.0/(32768*8);
130
avctx->
sample_fmt
=
AV_SAMPLE_FMT_FLT
;
131
}
else
{
132
s->
scale_bias
= 1.0/(1*8);
133
avctx->
sample_fmt
=
AV_SAMPLE_FMT_S16
;
134
ff_fmt_convert_init
(&s->
fmt_conv
, avctx);
135
s->
float_buf
=
av_mallocz
(
NELLY_SAMPLES
*
sizeof
(*s->
float_buf
));
136
if
(!s->
float_buf
) {
137
av_log
(avctx,
AV_LOG_ERROR
,
"error allocating float buffer\n"
);
138
return
AVERROR
(ENOMEM);
139
}
140
}
141
142
/* Generate overlap window */
143
if
(!ff_sine_128[127])
144
ff_init_ff_sine_windows
(7);
145
146
avctx->
channel_layout
=
AV_CH_LAYOUT_MONO
;
147
148
avcodec_get_frame_defaults
(&s->
frame
);
149
avctx->
coded_frame
= &s->
frame
;
150
151
return
0;
152
}
153
154
static
int
decode_tag
(
AVCodecContext
*avctx,
void
*
data
,
155
int
*got_frame_ptr,
AVPacket
*avpkt)
156
{
157
const
uint8_t *buf = avpkt->
data
;
158
int
buf_size = avpkt->
size
;
159
NellyMoserDecodeContext
*s = avctx->
priv_data
;
160
int
blocks, i, ret;
161
int16_t *samples_s16;
162
float
*samples_flt;
163
164
blocks = buf_size /
NELLY_BLOCK_LEN
;
165
if
(blocks <= 0) {
166
av_log
(avctx,
AV_LOG_ERROR
,
"Packet is too small\n"
);
167
return
AVERROR_INVALIDDATA
;
168
}
169
if
(buf_size %
NELLY_BLOCK_LEN
) {
170
av_log
(avctx,
AV_LOG_WARNING
,
"Leftover bytes: %d.\n"
,
171
buf_size % NELLY_BLOCK_LEN);
172
}
173
/* Normal numbers of blocks for sample rates:
174
* 8000 Hz - 1
175
* 11025 Hz - 2
176
* 16000 Hz - 3
177
* 22050 Hz - 4
178
* 44100 Hz - 8
179
*/
180
181
/* get output buffer */
182
s->
frame
.
nb_samples
=
NELLY_SAMPLES
* blocks;
183
if
((ret =
ff_get_buffer
(avctx, &s->
frame
)) < 0) {
184
av_log
(avctx,
AV_LOG_ERROR
,
"get_buffer() failed\n"
);
185
return
ret;
186
}
187
samples_s16 = (int16_t *)s->
frame
.
data
[0];
188
samples_flt = (
float
*)s->
frame
.
data
[0];
189
190
for
(i=0 ; i<blocks ; i++) {
191
if
(avctx->
sample_fmt
==
AV_SAMPLE_FMT_FLT
) {
192
nelly_decode_block
(s, buf, samples_flt);
193
samples_flt +=
NELLY_SAMPLES
;
194
}
else
{
195
nelly_decode_block
(s, buf, s->
float_buf
);
196
s->
fmt_conv
.
float_to_int16
(samples_s16, s->
float_buf
,
NELLY_SAMPLES
);
197
samples_s16 +=
NELLY_SAMPLES
;
198
}
199
buf +=
NELLY_BLOCK_LEN
;
200
}
201
202
*got_frame_ptr = 1;
203
*(
AVFrame
*)data = s->
frame
;
204
205
return
buf_size;
206
}
207
208
static
av_cold
int
decode_end
(
AVCodecContext
* avctx) {
209
NellyMoserDecodeContext
*s = avctx->
priv_data
;
210
211
av_freep
(&s->
float_buf
);
212
ff_mdct_end
(&s->
imdct_ctx
);
213
214
return
0;
215
}
216
217
AVCodec
ff_nellymoser_decoder
= {
218
.
name
=
"nellymoser"
,
219
.type =
AVMEDIA_TYPE_AUDIO
,
220
.id =
CODEC_ID_NELLYMOSER
,
221
.priv_data_size =
sizeof
(
NellyMoserDecodeContext
),
222
.
init
=
decode_init
,
223
.
close
=
decode_end
,
224
.
decode
=
decode_tag
,
225
.capabilities =
CODEC_CAP_DR1
|
CODEC_CAP_PARAM_CHANGE
,
226
.long_name =
NULL_IF_CONFIG_SMALL
(
"Nellymoser Asao"
),
227
.sample_fmts = (
const
enum
AVSampleFormat
[]) {
AV_SAMPLE_FMT_FLT
,
228
AV_SAMPLE_FMT_S16
,
229
AV_SAMPLE_FMT_NONE
},
230
};
231