rendered paste body/*
* 8SVX Audio Decoder
* Copyright (C) 2008 Jaikrishnan Menon
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file 8svx.c
* 8SVX Audio Decoder
* @author Jaikrishnan Menon
* Supports: Fibonacci delta encoding
* : Exponential encoding
*/
#include <stdio.h>
#include <stdlib.h>
#include "avcodec.h"
/*
* Decoder context
*/
typedef struct EightSvxContext {
int8_t fib_acc;
int first_frame;
} EightSvxContext;
int *table;
static const int fibonacci[16] = { -34, -21, -13, -8, -5, -3, -2, -1, 0, 1, 2, 3, 5, 8, 13, 21 };
static const int exponential[16] = {-128, -64, -32, -16, -8, -4, -2, -1, 0, 1, 2, 4, 8, 16, 32, 64 };
/*
*
* Decode a frame
*
*/
static int eightsvx_decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size)
{
EightSvxContext *esc = avctx->priv_data;
int8_t *in_data = buf, *out_data = data;
int i;
uint8_t d;
if(!buf_size)
return 0;
if(esc->first_frame)
{
esc->fib_acc = in_data[1];
in_data++;
}
for(i = 0;i < buf_size - (esc->first_frame << 1);i++)
{
d = *in_data;
esc->fib_acc += table[(uint8_t)d & 0x0f];
*out_data = esc->fib_acc;
out_data++;
esc->fib_acc += table[(uint8_t)d >> 4];
*out_data = esc->fib_acc;
out_data++;
*data_size += 2;
}
esc->first_frame = 0;
return buf_size;
}
/*
*
* Init 8svx decoder
*
*/
static av_cold int eightsvx_decode_init(AVCodecContext *avctx)
{
EightSvxContext *esc = avctx->priv_data;
esc->first_frame = 1;
esc->fib_acc = 0;
switch(avctx->codec->id)
{
case CODEC_ID_8SVX_FIB:
table = &fibonacci[0];
break;
case CODEC_ID_8SVX_EXP:
table = &exponential[0];
break;
default:
return 0;
}
return 0;
}
AVCodec eightsvx_fib_decoder = {
.name = "8svx fibonacci decoder",
.type = CODEC_TYPE_AUDIO,
.id = CODEC_ID_8SVX_FIB,
.priv_data_size = sizeof (EightSvxContext),
.init = eightsvx_decode_init,
.decode = eightsvx_decode_frame,
};
AVCodec eightsvx_exp_decoder = {
.name = "8svx exponential decoder",
.type = CODEC_TYPE_AUDIO,
.id = CODEC_ID_8SVX_EXP,
.priv_data_size = sizeof (EightSvxContext),
.init = eightsvx_decode_init,
.decode = eightsvx_decode_frame,
};