shithub: sox

Download patch

ref: 22a16468c8b39d1333d4489432a2e010883d3aa2
parent: 5cf04f8704d8e00c536968a138354a4f7c891392
author: cbagwell <cbagwell>
date: Wed Sep 29 09:12:33 EDT 1999

Adding avr.c file.

--- /dev/null
+++ b/src/avr.c
@@ -1,0 +1,281 @@
+/*
+
+    AVR file format driver for SOX
+    Copyright (C) 1999 Jan Paul Schmidt <jps@fundament.org>
+
+    This source code is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This source code 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 General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "st.h"
+
+#define AVR_MAGIC "2BIT"
+
+/* Taken from the Audio File Formats FAQ */
+
+typedef struct avrstuff {
+  char magic [4];      /* 2BIT */
+  char name [8];       /* null-padded sample name */
+  unsigned short mono; /* 0 = mono, 0xffff = stereo */
+  unsigned short rez;  /* 8 = 8 bit, 16 = 16 bit */
+  unsigned short sign; /* 0 = unsigned, 0xffff = signed */
+  unsigned short loop; /* 0 = no loop, 0xffff = looping sample */
+  unsigned short midi; /* 0xffff = no MIDI note assigned,
+			  0xffXX = single key note assignment
+			  0xLLHH = key split, low/hi note */
+  ULONG int rate;	       /* sample frequency in hertz */
+  ULONG size;	       /* sample length in bytes or words (see rez) */
+  ULONG lbeg;	       /* offset to start of loop in bytes or words.
+			  set to zero if unused. */
+  ULONG lend;	       /* offset to end of loop in bytes or words.
+			  set to sample length if unused. */
+  unsigned short res1; /* Reserved, MIDI keyboard split */
+  unsigned short res2; /* Reserved, sample compression */
+  unsigned short res3; /* Reserved */
+  char ext[20];	       /* Additional filename space, used
+			  if (name[7] != 0) */
+  char user[64];       /* User defined. Typically ASCII message. */
+} *avr_t;
+
+
+
+/*
+ * Do anything required before you start reading samples.
+ * Read file header. 
+ *	Find out sampling rate, 
+ *	size and style of samples, 
+ *	mono/stereo/quad.
+ */
+
+void
+avrstartread(ft) 
+ft_t ft;
+{
+  avr_t	avr = (avr_t)ft->priv;
+  int littlendian = 1;
+  char *endptr;
+
+  /* AVR is a Big Endian format.  Swap whats read in on Little */
+  /* Endian machines.					       */
+  endptr = (char *) &littlendian;
+  if (*endptr)
+  {
+	  ft->swap = ft->swap ? 0 : 1;
+  }
+
+  rawstartread (ft);
+
+  fread (avr->magic, 1, sizeof (avr->magic), ft->fp);
+
+  if (strncmp (avr->magic, AVR_MAGIC, 4)) {
+    fail ("AVR: unknown header");
+  }
+
+  fread (avr->name, 1, sizeof (avr->name), ft->fp);
+
+  avr->mono = rshort (ft);
+  if (avr->mono) {
+    ft->info.channels = 2;
+  }
+  else {
+    ft->info.channels = 1;
+  }
+
+  avr->rez = rshort (ft);
+  if (avr->rez == 8) {
+    ft->info.size = BYTE;
+  }
+  else if (avr->rez == 16) {
+    ft->info.size = WORD;
+  }
+  else {
+    fail ("AVR: unsupported sample resolution");
+  }
+
+  avr->sign = rshort (ft);
+  if (avr->sign) {
+    ft->info.style = SIGN2;
+  }
+  else {
+    ft->info.style = UNSIGNED;
+  }
+
+  avr->loop = rshort (ft);
+
+  avr->midi = rshort (ft);
+
+  avr->rate = rlong (ft);
+  /*
+   * No support for AVRs created by ST-Replay,
+   * Replay Proffesional and PRO-Series 12.
+   *
+   * Just masking the upper byte out.
+   */
+  ft->info.rate = (avr->rate & 0x00ffffff);
+
+  avr->size = rlong (ft);
+
+  avr->lbeg = rlong (ft);
+
+  avr->lend = rlong (ft);
+
+  avr->res1 = rshort (ft);
+
+  avr->res2 = rshort (ft);
+
+  avr->res3 = rshort (ft);
+
+  fread (avr->ext, 1, sizeof (avr->ext), ft->fp);
+
+  fread (avr->user, 1, sizeof (avr->user), ft->fp);
+}
+
+
+
+void
+avrstartwrite(ft) 
+ft_t ft;
+{
+  avr_t	avr = (avr_t)ft->priv;
+  int littlendian = 1;
+  char *endptr;
+
+  /* AVR is a Big Endian format.  Swap whats read in on Little */
+  /* Endian machines.					       */
+  endptr = (char *) &littlendian;
+  if (*endptr)
+  {
+	  ft->swap = ft->swap ? 0 : 1;
+  }
+
+  if (!ft->seekable) {
+    fail ("AVR: file is not seekable");
+  }
+
+  rawstartwrite (ft);
+
+  /* magic */
+  fwrite (AVR_MAGIC, 1, sizeof (avr->magic), ft->fp);
+
+  /* name */
+  fwrite ("\0\0\0\0\0\0\0\0", 1, sizeof (avr->name), ft->fp);
+
+  /* mono */
+  if (ft->info.channels == 1) {
+    wshort (ft, 0);
+  }
+  else if (ft->info.channels == 2) {
+    wshort (ft, 0xffff);
+  }
+  else {
+    fail ("AVR: number of channels not supported");
+  }
+
+  /* rez */
+  if (ft->info.size == BYTE) {
+    wshort (ft, 8);
+  }
+  else if (ft->info.size == WORD) {
+    wshort (ft, 16);
+  }
+  else {
+    fail ("AVR: unsupported sample resolution");
+  }
+
+  /* sign */
+  if (ft->info.style == SIGN2) {
+    wshort (ft, 0xffff);
+  }
+  else if (ft->info.style == UNSIGNED) {
+    wshort (ft, 0);
+  }
+  else {
+    fail ("AVR: unsupported style");
+  }
+
+  /* loop */
+  wshort (ft, 0xffff);
+
+  /* midi */
+  wshort (ft, 0xffff);
+
+  /* rate */
+  wlong (ft, ft->info.rate);
+
+  /* size */
+  /* Don't know the size yet. */
+  wlong (ft, 0);
+
+  /* lbeg */
+  wlong (ft, 0);
+
+  /* lend */
+  /* Don't know the size yet, so we can't set lend, either. */
+  wlong (ft, 0);
+
+  /* res1 */
+  wshort (ft, 0);
+
+  /* res2 */
+  wshort (ft, 0);
+
+  /* res3 */
+  wshort (ft, 0);
+
+  /* ext */
+  fwrite ("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 1, sizeof (avr->ext),
+          ft->fp);
+
+  /* user */
+  fwrite ("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+          "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+          "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+          "\0\0\0\0", 1, sizeof (avr->user), ft->fp);
+}
+
+
+
+void
+avrwrite(ft, buf, nsamp) 
+ft_t ft;
+LONG *buf, nsamp;
+{
+  avr_t	avr = (avr_t)ft->priv;
+
+  avr->size += nsamp;
+
+  rawwrite (ft, buf, nsamp);
+}
+
+
+
+void
+avrstopwrite(ft) 
+ft_t ft;
+{
+  avr_t	avr = (avr_t)ft->priv;
+
+  int size = avr->size / ft->info.channels;
+
+  /* Fix size */
+  fseek (ft->fp, 26L, SEEK_SET);
+  wlong (ft, size);
+
+  /* Fix lend */
+  fseek (ft->fp, 34L, SEEK_SET);
+  wlong (ft, size);
+}