view src/shnplug/vario.c @ 2284:d19b53359b24

cleaned up the sndfile wav plugin, currently limiting it ONLY TO WAV PLAYBACK. if somebody is more experienced with it and wants to restore the other formats, go ahead (maybe change the name of the plugin too?).
author mf0102 <0102@gmx.at>
date Wed, 09 Jan 2008 15:41:22 +0100
parents fa9f85cebade
children
line wrap: on
line source

/******************************************************************************
*                                                                             *
*  Copyright (C) 1992-1995 Tony Robinson                                      *
*                                                                             *
*  See the file doc/LICENSE.shorten for conditions on distribution and usage  *
*                                                                             *
******************************************************************************/

/*
 * $Id: vario.c,v 1.10 2004/05/04 02:26:36 jason Exp $
 */

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "shorten.h"

#define MASKTABSIZE 33
ulong masktab[MASKTABSIZE];

void mkmasktab() {
  int i;
  ulong val = 0;

  masktab[0] = val;
  for(i = 1; i < MASKTABSIZE; i++) {
    val <<= 1;
    val |= 1;
    masktab[i] = val;
  }
}

void var_get_init(shn_file *this_shn)
{
  mkmasktab();

  this_shn->decode_state->getbuf   = (uchar*) pmalloc((ulong) BUFSIZ,this_shn);
  this_shn->decode_state->getbufp  = this_shn->decode_state->getbuf;
  this_shn->decode_state->nbyteget = 0;
  this_shn->decode_state->gbuffer  = 0;
  this_shn->decode_state->nbitget  = 0;
}

ulong word_get(shn_file *this_shn)
{
  ulong buffer;
  int bytes;

  if(this_shn->decode_state->nbyteget < 4)
  {
    this_shn->vars.last_file_position = this_shn->vars.bytes_read;

    bytes = aud_vfs_fread((uchar*) this_shn->decode_state->getbuf, 1, BUFSIZ, this_shn->vars.fd);
    this_shn->decode_state->nbyteget += bytes;

    if(this_shn->decode_state->nbyteget < 4) {
      shn_error_fatal(this_shn,"Premature EOF on compressed stream -\npossible corrupt or truncated file");
      return (ulong)0;
    }

    this_shn->vars.bytes_read += bytes;

    this_shn->decode_state->getbufp = this_shn->decode_state->getbuf;
  }

  buffer = (((slong) (this_shn->decode_state->getbufp[0])) << 24) | (((slong) (this_shn->decode_state->getbufp[1])) << 16) |
    (((slong) (this_shn->decode_state->getbufp[2])) <<  8) | ((slong) (this_shn->decode_state->getbufp[3]));

  this_shn->decode_state->getbufp += 4;
  this_shn->decode_state->nbyteget -= 4;

  return(buffer);
}

slong uvar_get(int nbin,shn_file *this_shn)
{
  slong result;

  if (this_shn->vars.reading_function_code) {
    this_shn->vars.last_file_position_no_really = this_shn->vars.last_file_position;
  }

  if(this_shn->decode_state->nbitget == 0)
  {
    this_shn->decode_state->gbuffer = word_get(this_shn);
    if (this_shn->vars.fatal_error)
      return (ulong)0;
    this_shn->decode_state->nbitget = 32;
  }

  for(result = 0; !(this_shn->decode_state->gbuffer & (1L << --(this_shn->decode_state->nbitget))); result++)
  {
    if(this_shn->decode_state->nbitget == 0)
    {
      this_shn->decode_state->gbuffer = word_get(this_shn);
      if (this_shn->vars.fatal_error)
        return (ulong)0;
      this_shn->decode_state->nbitget = 32;
    }
  }

  while(nbin != 0)
  {
    if(this_shn->decode_state->nbitget >= nbin)
    {
      result = (result << nbin) | ((this_shn->decode_state->gbuffer >> (this_shn->decode_state->nbitget-nbin)) &masktab[nbin]);
      this_shn->decode_state->nbitget -= nbin;
      nbin = 0;
    }
    else
    {
      result = (result << this_shn->decode_state->nbitget) | (this_shn->decode_state->gbuffer & masktab[this_shn->decode_state->nbitget]);
      this_shn->decode_state->gbuffer = word_get(this_shn);
      if (this_shn->vars.fatal_error)
        return (ulong)0;
      nbin -= this_shn->decode_state->nbitget;
      this_shn->decode_state->nbitget = 32;
    }
  }

  return(result);
}

ulong ulong_get(shn_file *this_shn)
{
  unsigned int nbit = uvar_get(ULONGSIZE,this_shn);
  if (this_shn->vars.fatal_error)
    return (ulong)0;
  return(uvar_get(nbit,this_shn));
}

slong var_get(int nbin,shn_file *this_shn)
{
  ulong uvar = uvar_get(nbin + 1,this_shn);
  if (this_shn->vars.fatal_error)
    return (slong)0;

  if(uvar & 1) return((slong) ~(uvar >> 1));
  else return((slong) (uvar >> 1));
}

void var_get_quit(shn_file *this_shn)
{
  free((void *) this_shn->decode_state->getbuf);
  this_shn->decode_state->getbuf = NULL;
}