/* * 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 #include #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, };