summaryrefslogtreecommitdiff
path: root/plugins/shn/vario.c
diff options
context:
space:
mode:
authorGravatar Alexey Yakovenko <wakeroid@gmail.com>2010-06-20 20:29:25 +0200
committerGravatar Alexey Yakovenko <wakeroid@gmail.com>2010-06-20 20:29:25 +0200
commit7088867879c41de81e485f79f60cd2bb08d456d1 (patch)
tree41cbc372885a640681be3aa5551cef43718ea653 /plugins/shn/vario.c
parent9300f16316eb33715193a0f9a916991a2b24ba9d (diff)
initial port of xmms-shorten plugin
no gapless playback, no configuration, no sample-accurate seeking
Diffstat (limited to 'plugins/shn/vario.c')
-rw-r--r--plugins/shn/vario.c146
1 files changed, 146 insertions, 0 deletions
diff --git a/plugins/shn/vario.c b/plugins/shn/vario.c
new file mode 100644
index 00000000..988e2eb8
--- /dev/null
+++ b/plugins/shn/vario.c
@@ -0,0 +1,146 @@
+/******************************************************************************
+* *
+* 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 = deadbeef->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;
+}