FFmpeg
Loading...
Searching...
No Matches
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 * implementers. The original code is available from http://code.google.com/p/nelly2pcm/
32 */
33
35#include "libavutil/float_dsp.h"
36#include "libavutil/lfg.h"
37#include "libavutil/mem.h"
39#include "libavutil/tx.h"
40
41#define BITSTREAM_READER_LE
42#include "avcodec.h"
43#include "codec_internal.h"
44#include "decode.h"
45#include "get_bits.h"
46#include "nellymoser.h"
47#include "sinewin.h"
48
49
62
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;
71 unsigned char v;
72
74
75 bptr = buf;
76 pptr = pows;
78 for (i=0 ; i<NELLY_BANDS ; i++) {
79 if (i > 0)
81 pval = -exp2(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
90
91 for (i = 0; i < 2; i++) {
92 aptr = audio + i * NELLY_BUF_LEN;
93
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_fn(s->imdct_ctx, s->imdct_out, aptr, sizeof(float));
111 s->fdsp->vector_fmul_window(aptr, s->imdct_prev + NELLY_BUF_LEN / 2,
112 s->imdct_out, ff_sine_128,
113 NELLY_BUF_LEN / 2);
114 FFSWAP(float *, s->imdct_out, s->imdct_prev);
115 }
116}
117
119{
120 int ret;
121 float scale = 1.0f;
123
124 s->avctx = avctx;
125 s->imdct_out = s->imdct_buf[0];
126 s->imdct_prev = s->imdct_buf[1];
127 av_lfg_init(&s->random_state, 0);
128 if ((ret = av_tx_init(&s->imdct_ctx, &s->imdct_fn, AV_TX_FLOAT_MDCT,
129 1, 128, &scale, 0)) < 0)
130 return ret;
131
133 if (!s->fdsp)
134 return AVERROR(ENOMEM);
135
136 s->scale_bias = 1.0/(32768*8);
138
141
142 /* Generate overlap window */
144
145 return 0;
146}
147
149 int *got_frame_ptr, AVPacket *avpkt)
150{
151 const uint8_t *buf = avpkt->data;
152 int buf_size = avpkt->size;
154 int blocks, i, ret;
155 float *samples_flt;
156
157 blocks = buf_size / NELLY_BLOCK_LEN;
158
159 if (blocks <= 0 || blocks > INT_MAX / NELLY_SAMPLES) {
160 av_log(avctx, AV_LOG_ERROR, "Packet is too small or too large\n");
161 return AVERROR_INVALIDDATA;
162 }
163
164 if (buf_size % NELLY_BLOCK_LEN) {
165 av_log(avctx, AV_LOG_WARNING, "Leftover bytes: %d.\n",
166 buf_size % NELLY_BLOCK_LEN);
167 }
168
169 /* get output buffer */
170 frame->nb_samples = NELLY_SAMPLES * blocks;
171 if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
172 return ret;
173 samples_flt = (float *)frame->data[0];
174
175 for (i=0 ; i<blocks ; i++) {
176 nelly_decode_block(s, buf, samples_flt);
177 samples_flt += NELLY_SAMPLES;
178 buf += NELLY_BLOCK_LEN;
179 }
180
181 *got_frame_ptr = 1;
182
183 return buf_size;
184}
185
186static av_cold int decode_end(AVCodecContext * avctx) {
188
189 av_tx_uninit(&s->imdct_ctx);
190 av_freep(&s->fdsp);
191
192 return 0;
193}
194
196 .p.name = "nellymoser",
197 CODEC_LONG_NAME("Nellymoser Asao"),
198 .p.type = AVMEDIA_TYPE_AUDIO,
200 .priv_data_size = sizeof(NellyMoserDecodeContext),
201 .init = decode_init,
202 .close = decode_end,
205};
static double val(void *priv, double ch)
Definition aeval.c:77
const FFCodec ff_nellymoser_decoder
static av_cold void close(AVCodecParserContext *s)
Definition apv_parser.c:197
Libavcodec external API header.
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
Public libavutil channel layout APIs header.
#define FF_CODEC_DECODE_CB(func)
#define CODEC_LONG_NAME(str)
static int16_t block[64]
Definition dct.c:125
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition decode.c:1777
static AVFrame * frame
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
static const uint8_t bits[8]
Definition fastaudio.c:100
bitstream reader API header.
static void skip_bits_long(GetBitContext *s, int n)
Skips the specified number of bits.
Definition get_bits.h:280
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition get_bits.h:337
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition get_bits.h:517
#define AV_CODEC_FLAG_BITEXACT
Use only bitexact stuff (except (I)DCT).
Definition avcodec.h:322
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition codec.h:49
#define AV_CODEC_CAP_CHANNEL_CONF
Codec should fill in channel configuration and samplerate instead of container.
Definition codec.h:94
#define AV_CODEC_CAP_PARAM_CHANGE
Codec supports changed parameters at any point.
Definition codec.h:106
@ AV_CODEC_ID_NELLYMOSER
Definition codec_id.h:486
#define AV_CHANNEL_LAYOUT_MONO
void av_channel_layout_uninit(AVChannelLayout *channel_layout)
Free any allocated data in the channel layout and reset the channel count to 0.
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
@ AVMEDIA_TYPE_AUDIO
Definition avutil.h:201
@ AV_SAMPLE_FMT_FLT
float
Definition samplefmt.h:60
static void scale(int *out, const int *in, const int w, const int h, const int shift)
Definition intra.c:278
av_cold void av_lfg_init(AVLFG *c, unsigned int seed)
Definition lfg.c:32
static unsigned int av_lfg_get(AVLFG *c)
Get the next random unsigned 32-bit number using an ALFG.
Definition lfg.h:53
static av_cold int decode_init(AVCodecContext *avctx)
Definition 4xm.c:998
static av_cold int decode_end(AVCodecContext *avctx)
Definition 4xm.c:980
#define av_cold
Definition attributes.h:117
av_cold AVFloatDSPContext * avpriv_float_dsp_alloc(int bit_exact)
Allocate a float DSP context.
Definition float_dsp.c:135
#define exp2(x)
Definition libm.h:290
#define FFSWAP(type, a, b)
Definition macros.h:52
#define M_SQRT1_2
Memory handling functions.
#define DECLARE_ALIGNED(n, t, v)
Declare a variable that is aligned in memory.
const uint16_t ff_nelly_init_table[64]
Definition nellymoser.c:72
const uint8_t ff_nelly_band_sizes_table[NELLY_BANDS]
Definition nellymoser.c:68
void ff_nelly_get_sample_bits(const float *buf, int *bits)
Definition nellymoser.c:118
const int16_t ff_nelly_delta_table[32]
Definition nellymoser.c:81
const float ff_nelly_dequantization_table[127]
Definition nellymoser.c:41
The 3 alphanumeric copyright notices are md5summed they are from the original implementers.
#define NELLY_BANDS
Definition nellymoser.h:39
#define NELLY_BUF_LEN
Definition nellymoser.h:43
#define NELLY_DETAIL_BITS
Definition nellymoser.h:42
#define NELLY_SAMPLES
Definition nellymoser.h:48
#define NELLY_HEADER_BITS
Definition nellymoser.h:41
#define NELLY_FILL_LEN
Definition nellymoser.h:44
#define NELLY_BLOCK_LEN
Definition nellymoser.h:40
static av_cold int decode_init(AVCodecContext *avctx)
static int decode_tag(AVCodecContext *avctx, AVFrame *frame, int *got_frame_ptr, AVPacket *avpkt)
static av_cold int decode_end(AVCodecContext *avctx)
static void nelly_decode_block(NellyMoserDecodeContext *s, const unsigned char block[NELLY_BLOCK_LEN], float audio[NELLY_SAMPLES])
void ff_init_ff_sine_windows(int index)
initialize the specified entry of ff_sine_windows
An AVChannelLayout holds information about the channel layout of audio data.
main external API structure.
Definition avcodec.h:443
AVChannelLayout ch_layout
Audio channel layout.
Definition avcodec.h:1055
enum AVSampleFormat sample_fmt
audio sample format
Definition avcodec.h:1047
int flags
AV_CODEC_FLAG_*.
Definition avcodec.h:500
void * priv_data
Definition avcodec.h:470
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
Context structure for the Lagged Fibonacci PRNG.
Definition lfg.h:33
This structure stores compressed data.
Definition packet.h:580
int size
Definition packet.h:604
uint8_t * data
Definition packet.h:603
AVFloatDSPContext * fdsp
float imdct_buf[2][NELLY_BUF_LEN]
AVCodecContext * avctx
#define av_freep(p)
#define av_log(a,...)
av_cold void av_tx_uninit(AVTXContext **ctx)
Frees a context and sets *ctx to NULL, does nothing when *ctx == NULL.
Definition tx.c:295
av_cold int av_tx_init(AVTXContext **ctx, av_tx_fn *tx, enum AVTXType type, int inv, int len, const void *scale, uint64_t flags)
Initialize a transform context with the given configuration (i)MDCTs with an odd length are currently...
Definition tx.c:903
@ AV_TX_FLOAT_MDCT
Standard MDCT with a sample data type of float, double or int32_t, respectively.
Definition tx.h:68
void(* av_tx_fn)(AVTXContext *s, void *out, void *in, ptrdiff_t stride)
Function pointer to a function to perform the transform.
Definition tx.h:151