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 "
dsputil.h
"
40
#include "
fft.h
"
41
#include "
fmtconvert.h
"
42
#include "
sinewin.h
"
43
44
#define BITSTREAM_READER_LE
45
#include "
get_bits.h
"
46
47
48
typedef
struct
NellyMoserDecodeContext
{
49
AVCodecContext
*
avctx
;
50
AVFrame
frame
;
51
float
*
float_buf
;
52
DECLARE_ALIGNED
(16,
float
,
state
)[
NELLY_BUF_LEN
];
53
AVLFG
random_state
;
54
GetBitContext
gb
;
55
float
scale_bias
;
56
DSPContext
dsp
;
57
FFTContext
imdct_ctx
;
58
FmtConvertContext
fmt_conv
;
59
DECLARE_ALIGNED
(32,
float
,
imdct_out
)[
NELLY_BUF_LEN
* 2];
60
}
NellyMoserDecodeContext
;
61
62
static
void
nelly_decode_block
(
NellyMoserDecodeContext
*s,
63
const
unsigned
char
block
[
NELLY_BLOCK_LEN
],
64
float
audio[
NELLY_SAMPLES
])
65
{
66
int
i,j;
67
float
buf[
NELLY_FILL_LEN
], pows[
NELLY_FILL_LEN
];
68
float
*aptr, *bptr, *pptr, val, pval;
69
int
bits
[
NELLY_BUF_LEN
];
70
unsigned
char
v
;
71
72
init_get_bits
(&s->
gb
,
block
, NELLY_BLOCK_LEN * 8);
73
74
bptr = buf;
75
pptr = pows;
76
val =
ff_nelly_init_table
[
get_bits
(&s->
gb
, 6)];
77
for
(i=0 ; i<
NELLY_BANDS
; i++) {
78
if
(i > 0)
79
val +=
ff_nelly_delta_table
[
get_bits
(&s->
gb
, 5)];
80
pval = -pow(2, val/2048) * s->
scale_bias
;
81
for
(j = 0; j <
ff_nelly_band_sizes_table
[i]; j++) {
82
*bptr++ = val;
83
*pptr++ = pval;
84
}
85
86
}
87
88
ff_nelly_get_sample_bits
(buf, bits);
89
90
for
(i = 0; i < 2; i++) {
91
aptr = audio + i *
NELLY_BUF_LEN
;
92
93
init_get_bits
(&s->
gb
,
block
, NELLY_BLOCK_LEN * 8);
94
skip_bits_long
(&s->
gb
,
NELLY_HEADER_BITS
+ i*
NELLY_DETAIL_BITS
);
95
96
for
(j = 0; j <
NELLY_FILL_LEN
; j++) {
97
if
(bits[j] <= 0) {
98
aptr[j] =
M_SQRT1_2
*pows[j];
99
if
(
av_lfg_get
(&s->
random_state
) & 1)
100
aptr[j] *= -1.0;
101
}
else
{
102
v =
get_bits
(&s->
gb
, bits[j]);
103
aptr[j] =
ff_nelly_dequantization_table
[(1<<bits[j])-1+v]*pows[j];
104
}
105
}
106
memset(&aptr[NELLY_FILL_LEN], 0,
107
(NELLY_BUF_LEN - NELLY_FILL_LEN) *
sizeof
(
float
));
108
109
s->
imdct_ctx
.
imdct_calc
(&s->
imdct_ctx
, s->
imdct_out
, aptr);
110
/* XXX: overlapping and windowing should be part of a more
111
generic imdct function */
112
s->
dsp
.
vector_fmul_reverse
(s->
state
, s->
state
, ff_sine_128, NELLY_BUF_LEN);
113
s->
dsp
.
vector_fmul_add
(aptr, s->
imdct_out
, ff_sine_128, s->
state
, NELLY_BUF_LEN);
114
memcpy(s->
state
, s->
imdct_out
+ NELLY_BUF_LEN,
sizeof
(
float
)*NELLY_BUF_LEN);
115
}
116
}
117
118
static
av_cold
int
decode_init
(
AVCodecContext
* avctx) {
119
NellyMoserDecodeContext
*s = avctx->
priv_data
;
120
121
s->
avctx
= avctx;
122
av_lfg_init
(&s->
random_state
, 0);
123
ff_mdct_init
(&s->
imdct_ctx
, 8, 1, 1.0);
124
125
dsputil_init
(&s->
dsp
, avctx);
126
127
if
(avctx->
request_sample_fmt
==
AV_SAMPLE_FMT_FLT
) {
128
s->
scale_bias
= 1.0/(32768*8);
129
avctx->
sample_fmt
=
AV_SAMPLE_FMT_FLT
;
130
}
else
{
131
s->
scale_bias
= 1.0/(1*8);
132
avctx->
sample_fmt
=
AV_SAMPLE_FMT_S16
;
133
ff_fmt_convert_init
(&s->
fmt_conv
, avctx);
134
s->
float_buf
=
av_mallocz
(
NELLY_SAMPLES
*
sizeof
(*s->
float_buf
));
135
if
(!s->
float_buf
) {
136
av_log
(avctx,
AV_LOG_ERROR
,
"error allocating float buffer\n"
);
137
return
AVERROR
(ENOMEM);
138
}
139
}
140
141
/* Generate overlap window */
142
if
(!ff_sine_128[127])
143
ff_init_ff_sine_windows
(7);
144
145
avctx->
channel_layout
=
AV_CH_LAYOUT_MONO
;
146
147
avcodec_get_frame_defaults
(&s->
frame
);
148
avctx->
coded_frame
= &s->
frame
;
149
150
return
0;
151
}
152
153
static
int
decode_tag
(
AVCodecContext
*avctx,
void
*
data
,
154
int
*got_frame_ptr,
AVPacket
*avpkt)
155
{
156
const
uint8_t *buf = avpkt->
data
;
157
int
buf_size = avpkt->
size
;
158
NellyMoserDecodeContext
*s = avctx->
priv_data
;
159
int
blocks, i, ret;
160
int16_t *samples_s16;
161
float
*samples_flt;
162
163
blocks = buf_size /
NELLY_BLOCK_LEN
;
164
if
(blocks <= 0) {
165
av_log
(avctx,
AV_LOG_ERROR
,
"Packet is too small\n"
);
166
return
AVERROR_INVALIDDATA
;
167
}
168
if
(buf_size %
NELLY_BLOCK_LEN
) {
169
av_log
(avctx,
AV_LOG_WARNING
,
"Leftover bytes: %d.\n"
,
170
buf_size % NELLY_BLOCK_LEN);
171
}
172
/* Normal numbers of blocks for sample rates:
173
* 8000 Hz - 1
174
* 11025 Hz - 2
175
* 16000 Hz - 3
176
* 22050 Hz - 4
177
* 44100 Hz - 8
178
*/
179
180
/* get output buffer */
181
s->
frame
.
nb_samples
=
NELLY_SAMPLES
* blocks;
182
if
((ret = avctx->
get_buffer
(avctx, &s->
frame
)) < 0) {
183
av_log
(avctx,
AV_LOG_ERROR
,
"get_buffer() failed\n"
);
184
return
ret;
185
}
186
samples_s16 = (int16_t *)s->
frame
.
data
[0];
187
samples_flt = (
float
*)s->
frame
.
data
[0];
188
189
for
(i=0 ; i<blocks ; i++) {
190
if
(avctx->
sample_fmt
==
AV_SAMPLE_FMT_FLT
) {
191
nelly_decode_block
(s, buf, samples_flt);
192
samples_flt +=
NELLY_SAMPLES
;
193
}
else
{
194
nelly_decode_block
(s, buf, s->
float_buf
);
195
s->
fmt_conv
.
float_to_int16
(samples_s16, s->
float_buf
,
NELLY_SAMPLES
);
196
samples_s16 +=
NELLY_SAMPLES
;
197
}
198
buf +=
NELLY_BLOCK_LEN
;
199
}
200
201
*got_frame_ptr = 1;
202
*(
AVFrame
*)data = s->
frame
;
203
204
return
buf_size;
205
}
206
207
static
av_cold
int
decode_end
(
AVCodecContext
* avctx) {
208
NellyMoserDecodeContext
*s = avctx->
priv_data
;
209
210
av_freep
(&s->
float_buf
);
211
ff_mdct_end
(&s->
imdct_ctx
);
212
213
return
0;
214
}
215
216
AVCodec
ff_nellymoser_decoder
= {
217
.
name
=
"nellymoser"
,
218
.type =
AVMEDIA_TYPE_AUDIO
,
219
.id =
CODEC_ID_NELLYMOSER
,
220
.priv_data_size =
sizeof
(
NellyMoserDecodeContext
),
221
.
init
=
decode_init
,
222
.
close
=
decode_end
,
223
.
decode
=
decode_tag
,
224
.capabilities =
CODEC_CAP_DR1
|
CODEC_CAP_PARAM_CHANGE
,
225
.long_name =
NULL_IF_CONFIG_SMALL
(
"Nellymoser Asao"
),
226
.sample_fmts = (
const
enum
AVSampleFormat
[]) {
AV_SAMPLE_FMT_FLT
,
227
AV_SAMPLE_FMT_S16
,
228
AV_SAMPLE_FMT_NONE
},
229
};
230