All pastes #956886 Raw Edit

Untitled

public text v1 · immutable
#956886 ·published 2008-03-25 17:04 UTC
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,
};