ref: 6b73c041d6ff5835ddbda5b65670426255f4c690
parent: 2cfab89817a38efdfb6422e3217e53695d4b0f5c
author: cbagwell <cbagwell>
date: Tue Aug 15 21:01:40 EDT 2000
Forgot to add new sphere file
--- /dev/null
+++ b/src/sphere.c
@@ -1,0 +1,265 @@
+/*
+ * August 7, 2000
+ *
+ * Copyright (C) 2000 Chris Bagwell (cbagwell@sprynet.com)
+ *
+ */
+
+/*
+ * NIST Sphere file format handler.
+ */
+
+#include <math.h>
+#include <string.h>
+#include "st.h"
+
+/* Private data for SKEL file */
+typedef struct spherestuff {
+ char shorten_check[4];
+} *sphere_t;
+
+/*
+ * Do anything required before you start reading samples.
+ * Read file header.
+ * Find out sampling rate,
+ * size and encoding of samples,
+ * mono/stereo/quad.
+ */
+int st_spherestartread(ft)
+ft_t ft;
+{
+ sphere_t sphere = (sphere_t) ft->priv;
+ int rc;
+ char buf[256];
+ char fldname[64], fldtype[16], fldsval[128];
+ int header_size, bytes_read;
+
+ /* Needed for rawread() */
+ rc = st_rawstartread(ft);
+ if (rc)
+ return rc;
+
+ /* Magic header */
+ if (st_reads(ft, buf, 8) == ST_EOF || strncmp(buf, "NIST_1A", 7) != 0)
+ {
+ st_fail("Sphere header does not begin with magic mord 'NIST_1A'");
+ return(ST_EOF);
+ }
+
+ if (st_reads(ft, fldsval, 8) == ST_EOF)
+ {
+ printf("%s\n",fldsval);
+ st_fail("Error reading Sphere header");
+ return(ST_EOF);
+ }
+
+ sscanf(fldsval, "%d", &header_size);
+
+ /* Skip what we have read so far */
+ header_size -= 16;
+
+ if (st_reads(ft, buf, 255) == ST_EOF)
+ {
+ st_fail("Error reading Sphere header");
+ return(ST_EOF);
+ }
+
+ header_size -= (strlen(buf) + 1);
+
+ while (strncmp(buf, "end_head", 8) != 0)
+ {
+ if (strncmp(buf, "sample_n_bytes", 14) == 0)
+ {
+ sscanf(buf, "%s %s %d", fldname, fldtype, &ft->info.size);
+ }
+ if (strncmp(buf, "channel_count", 13) == 0)
+ {
+ sscanf(buf, "%s %s %d", fldname, fldtype, &ft->info.channels);
+ }
+ if (strncmp(buf, "sample_coding", 13) == 0)
+ {
+ sscanf(buf, "%s %s %s", fldname, fldtype, fldsval);
+ /* Only bother looking for ulaw flag. All others
+ * should be caught below by default PCM check
+ */
+ if (strncmp(fldsval,"ulaw",4) == 0)
+ {
+ ft->info.encoding = ST_ENCODING_ULAW;
+ }
+ }
+ if (strncmp(buf, "sample_rate", 11) == 0)
+ {
+#ifdef __alpha__
+ sscanf(buf, "%s %s %d", fldname, fldtype, &ft->info.rate);
+#else
+ sscanf(buf, "%s %s %ld", fldname, fldtype, &ft->info.rate);
+#endif
+ }
+ if (strncmp(buf, "sample_byte_format", 18) == 0)
+ {
+ sscanf(buf, "%s %s %s", fldname, fldtype, fldsval);
+ if (strncmp(fldsval,"01",2) == 0)
+ {
+ /* Data is in little endian. */
+ if (ST_IS_BIGENDIAN)
+ {
+ ft->swap = ft->swap ? 0 : 1;
+ }
+ }
+ else if (strncmp(fldsval,"10",2) == 0)
+ {
+ /* Data is in big endian. */
+ if (ST_IS_LITTLEENDIAN)
+ {
+ ft->swap = ft->swap ? 0 : 1;
+ }
+ }
+ }
+
+ if (st_reads(ft, buf, 255) == ST_EOF)
+ {
+ st_fail("Error reading Sphere header");
+ return(ST_EOF);
+ }
+
+ header_size -= (strlen(buf) + 1);
+ }
+
+ if (ft->info.size == -1)
+ ft->info.size = 1;
+
+ /* sample_coding is optional and is PCM if missing.
+ * This means encoding is signed if size = word or
+ * unsigned if size = byte.
+ */
+ if (ft->info.encoding == -1)
+ {
+ if (ft->info.size == 1)
+ ft->info.encoding = ST_ENCODING_UNSIGNED;
+ else
+ ft->info.encoding = ST_ENCODING_SIGN2;
+ }
+
+ while (header_size)
+ {
+ bytes_read = st_read(ft, buf, ST_SIZE_BYTE, (header_size > 256) ? 256 : header_size);
+ if (bytes_read == 0)
+ {
+ return(ST_EOF);
+ }
+ header_size -= bytes_read;
+ }
+
+ sphere->shorten_check[0] = 0;
+#if 0
+ st_reads(ft, sphere->shorten_check, 4);
+
+ if (!strcmp(sphere->shorten_check,"abcd"))
+ {
+ st_fail("File uses shorten compression, can not handle this.\n");
+ return(ST_EOF);
+ }
+#endif
+
+ return (ST_SUCCESS);
+}
+
+/*
+ * Read up to len samples from file.
+ * Convert to signed longs.
+ * Place in buf[].
+ * Return number of samples read.
+ */
+
+LONG st_sphereread(ft, buf, len)
+ft_t ft;
+LONG *buf, len;
+{
+ sphere_t sphere = (sphere_t) ft->priv;
+
+ if (sphere->shorten_check[0])
+ {
+ sphere->shorten_check[0] = 0;
+ }
+ return st_rawread(ft, buf, len);
+}
+
+int st_spherestartwrite(ft)
+ft_t ft;
+{
+ int rc;
+ int x;
+
+ if (!ft->seekable)
+ {
+ st_fail("File must be seekable for sphere file output");
+ return (ST_EOF);
+ }
+
+ /* Needed for rawwrite */
+ rc = st_rawstartwrite(ft);
+ if (rc)
+ return rc;
+
+ for (x = 0; x < 1024; x++)
+ {
+ st_writeb(ft, ' ');
+ }
+
+ return(ST_SUCCESS);
+
+}
+
+int st_spherestopwrite(ft)
+ft_t ft;
+{
+ int rc;
+ char buf[128];
+
+ rc = st_rawstopwrite(ft);
+ if (rc)
+ return rc;
+
+ if (fseek(ft->fp, 0L, 0) != 0)
+ {
+ st_fail("Could not rewird output file to rewrite sphere header.\n");
+ return (ST_EOF);
+ }
+
+ st_writes(ft, "NIST_1A\n");
+ st_writes(ft, " 1024\n");
+
+ /* FIXME: Need sample_count */
+
+ sprintf(buf, "sample_n_bytes -i %d\n", ft->info.size);
+ st_writes(ft, buf);
+
+ sprintf(buf, "channel_count -i %d\n", ft->info.channels);
+ st_writes(ft, buf);
+
+ if (ft->swap)
+ {
+ sprintf(buf, "sample_byte_format -s2 %s\n", ST_IS_BIGENDIAN ? "01" : "10");
+ }
+ else
+ {
+ sprintf(buf, "sample_byte_format -s2 %s\n", ST_IS_BIGENDIAN ? "10" : "01");
+ }
+ st_writes(ft, buf);
+
+#ifdef __alpha__
+ sprintf(buf, "sample_rate -i %d\n", ft->info.rate);
+#else
+ sprintf(buf, "sample_rate -i %ld\n", ft->info.rate);
+#endif
+ st_writes(ft, buf);
+
+ if (ft->info.encoding == ST_ENCODING_ULAW)
+ st_writes(ft, "sample_coding -s4 ulaw\n");
+ else
+ st_writes(ft, "sample_coding -s3 pcm\n");
+
+ st_writes(ft, "end_head\n");
+
+ return (ST_SUCCESS);
+}