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
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
28
/**
29
* @file
30
* The 3 alphanumeric copyright notices are md5summed they are from the original
31
* implementors. The original code is available from http://code.google.com/p/nelly2pcm/
32
*/
33
34
#include "
libavutil/channel_layout.h
"
35
#include "
libavutil/float_dsp.h
"
36
#include "
libavutil/lfg.h
"
37
#include "
libavutil/random_seed.h
"
38
#include "
avcodec.h
"
39
#include "
fft.h
"
40
#include "
internal.h
"
41
#include "
nellymoser.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
AVLFG
random_state
;
51
GetBitContext
gb
;
52
float
scale_bias
;
53
AVFloatDSPContext
*
fdsp
;
54
FFTContext
imdct_ctx
;
55
DECLARE_ALIGNED
(32,
float
,
imdct_buf
)[2][
NELLY_BUF_LEN
];
56
float
*
imdct_out
;
57
float
*
imdct_prev
;
58
}
NellyMoserDecodeContext
;
59
60
static
void
nelly_decode_block
(
NellyMoserDecodeContext
*
s
,
61
const
unsigned
char
block
[
NELLY_BLOCK_LEN
],
62
float
audio[
NELLY_SAMPLES
])
63
{
64
int
i,j;
65
float
buf
[
NELLY_FILL_LEN
], pows[
NELLY_FILL_LEN
];
66
float
*aptr, *bptr, *pptr,
val
, pval;
67
int
bits
[
NELLY_BUF_LEN
];
68
unsigned
char
v
;
69
70
init_get_bits
(&s->
gb
,
block
, NELLY_BLOCK_LEN * 8);
71
72
bptr =
buf
;
73
pptr = pows;
74
val =
ff_nelly_init_table
[
get_bits
(&s->
gb
, 6)];
75
for
(i=0 ; i<
NELLY_BANDS
; i++) {
76
if
(i > 0)
77
val +=
ff_nelly_delta_table
[
get_bits
(&s->
gb
, 5)];
78
pval = -pow(2, val/2048) * s->
scale_bias
;
79
for
(j = 0; j <
ff_nelly_band_sizes_table
[i]; j++) {
80
*bptr++ =
val
;
81
*pptr++ = pval;
82
}
83
84
}
85
86
ff_nelly_get_sample_bits
(buf, bits);
87
88
for
(i = 0; i < 2; i++) {
89
aptr = audio + i *
NELLY_BUF_LEN
;
90
91
init_get_bits
(&s->
gb
,
block
, NELLY_BLOCK_LEN * 8);
92
skip_bits_long
(&s->
gb
,
NELLY_HEADER_BITS
+ i*
NELLY_DETAIL_BITS
);
93
94
for
(j = 0; j <
NELLY_FILL_LEN
; j++) {
95
if
(bits[j] <= 0) {
96
aptr[j] =
M_SQRT1_2
*pows[j];
97
if
(
av_lfg_get
(&s->
random_state
) & 1)
98
aptr[j] *= -1.0;
99
}
else
{
100
v =
get_bits
(&s->
gb
, bits[j]);
101
aptr[j] =
ff_nelly_dequantization_table
[(1<<bits[j])-1+v]*pows[j];
102
}
103
}
104
memset(&aptr[NELLY_FILL_LEN], 0,
105
(NELLY_BUF_LEN - NELLY_FILL_LEN) *
sizeof
(
float
));
106
107
s->
imdct_ctx
.
imdct_half
(&s->
imdct_ctx
, s->
imdct_out
, aptr);
108
s->
fdsp
->
vector_fmul_window
(aptr, s->
imdct_prev
+ NELLY_BUF_LEN / 2,
109
s->
imdct_out
, ff_sine_128,
110
NELLY_BUF_LEN / 2);
111
FFSWAP
(
float
*, s->
imdct_out
, s->
imdct_prev
);
112
}
113
}
114
115
static
av_cold
int
decode_init
(
AVCodecContext
* avctx) {
116
NellyMoserDecodeContext
*
s
= avctx->
priv_data
;
117
118
s->
avctx
= avctx;
119
s->
imdct_out
= s->
imdct_buf
[0];
120
s->
imdct_prev
= s->
imdct_buf
[1];
121
av_lfg_init
(&s->
random_state
, 0);
122
ff_mdct_init
(&s->
imdct_ctx
, 8, 1, 1.0);
123
124
s->
fdsp
=
avpriv_float_dsp_alloc
(avctx->
flags
&
CODEC_FLAG_BITEXACT
);
125
if
(!s->
fdsp
)
126
return
AVERROR
(ENOMEM);
127
128
s->
scale_bias
= 1.0/(32768*8);
129
avctx->
sample_fmt
=
AV_SAMPLE_FMT_FLT
;
130
131
/* Generate overlap window */
132
if
(!ff_sine_128[127])
133
ff_init_ff_sine_windows
(7);
134
135
avctx->
channels
= 1;
136
avctx->
channel_layout
=
AV_CH_LAYOUT_MONO
;
137
138
return
0;
139
}
140
141
static
int
decode_tag
(
AVCodecContext
*avctx,
void
*
data
,
142
int
*got_frame_ptr,
AVPacket
*avpkt)
143
{
144
AVFrame
*
frame
=
data
;
145
const
uint8_t
*
buf
= avpkt->
data
;
146
const
uint8_t
*side=
av_packet_get_side_data
(avpkt,
'F'
,
NULL
);
147
int
buf_size = avpkt->
size
;
148
NellyMoserDecodeContext
*
s
= avctx->
priv_data
;
149
int
blocks, i,
ret
;
150
float
*samples_flt;
151
152
blocks = buf_size /
NELLY_BLOCK_LEN
;
153
154
if
(blocks <= 0) {
155
av_log
(avctx,
AV_LOG_ERROR
,
"Packet is too small\n"
);
156
return
AVERROR_INVALIDDATA
;
157
}
158
159
if
(buf_size %
NELLY_BLOCK_LEN
) {
160
av_log
(avctx,
AV_LOG_WARNING
,
"Leftover bytes: %d.\n"
,
161
buf_size % NELLY_BLOCK_LEN);
162
}
163
/* Normal numbers of blocks for sample rates:
164
* 8000 Hz - 1
165
* 11025 Hz - 2
166
* 16000 Hz - 3
167
* 22050 Hz - 4
168
* 44100 Hz - 8
169
*/
170
if
(side && blocks>1 && avctx->
sample_rate
%11025==0 && (1<<((side[0]>>2)&3)) == blocks)
171
avctx->
sample_rate
= 11025*(blocks/2);
172
173
/* get output buffer */
174
frame->
nb_samples
=
NELLY_SAMPLES
* blocks;
175
if
((ret =
ff_get_buffer
(avctx, frame, 0)) < 0)
176
return
ret;
177
samples_flt = (
float
*)frame->
data
[0];
178
179
for
(i=0 ; i<blocks ; i++) {
180
nelly_decode_block
(s, buf, samples_flt);
181
samples_flt +=
NELLY_SAMPLES
;
182
buf +=
NELLY_BLOCK_LEN
;
183
}
184
185
*got_frame_ptr = 1;
186
187
return
buf_size;
188
}
189
190
static
av_cold
int
decode_end
(
AVCodecContext
* avctx) {
191
NellyMoserDecodeContext
*
s
= avctx->
priv_data
;
192
193
ff_mdct_end
(&s->
imdct_ctx
);
194
av_freep
(&s->
fdsp
);
195
196
return
0;
197
}
198
199
AVCodec
ff_nellymoser_decoder
= {
200
.
name
=
"nellymoser"
,
201
.long_name =
NULL_IF_CONFIG_SMALL
(
"Nellymoser Asao"
),
202
.type =
AVMEDIA_TYPE_AUDIO
,
203
.id =
AV_CODEC_ID_NELLYMOSER
,
204
.priv_data_size =
sizeof
(
NellyMoserDecodeContext
),
205
.
init
=
decode_init
,
206
.close =
decode_end
,
207
.
decode
=
decode_tag
,
208
.capabilities =
CODEC_CAP_DR1
|
CODEC_CAP_PARAM_CHANGE
,
209
.
sample_fmts
= (
const
enum
AVSampleFormat
[]) {
AV_SAMPLE_FMT_FLT
,
210
AV_SAMPLE_FMT_NONE
},
211
};
Generated on Sun Mar 8 2015 02:34:57 for FFmpeg by
1.8.2