shithub: sox

Download patch

ref: ec9b7b9d5afeee67ff0c39de79018037d426d3ba
parent: 5d2778c5745aef0ad4af9e4cadef948657c9d336
author: robs <robs>
date: Sat Oct 25 13:48:51 EDT 2008

updates to new sox format

--- a/src/formats.c
+++ b/src/formats.c
@@ -80,6 +80,8 @@
   MAGIC(sf    , 0, 0, ""     , 0,  4, "\144\243\003\0")
   MAGIC(sf    , 0, 0, ""     , 0,  4, "\0\003\243\144")
   MAGIC(sf    , 0, 0, ""     , 0,  4, "\144\243\004\0")
+  MAGIC(sox   , 0, 0, ""     , 0,  4, ".SoX")
+  MAGIC(sox   , 0, 0, ""     , 0,  4, "XoS.")
 
   if (ext && !strcasecmp(ext, "snd"))
   MAGIC(sndr  , 7, 1, ""     , 0,  2, "\0")
--- a/src/sox-fmt.c
+++ b/src/sox-fmt.c
@@ -1,4 +1,4 @@
-/* libSoX file format: SoX temporary   (c) 2008 robs@users.sourceforge.net
+/* libSoX file format: SoX native   (c) 2008 robs@users.sourceforge.net
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
@@ -19,38 +19,42 @@
 #include <string.h>
 
 static char const magic[4] = ".SoX";
-#define FIXED_HDR     (4 + 4 + 8 + 8 + 4)
+static char const cigam[4] = "XoS.";
+#define FIXED_HDR     (4 + 8 + 8 + 4 + 4) /* Without magic */
 
 static int startread(sox_format_t * ft)
 {
   char     magic_[sizeof(magic)];
-  uint32_t hdr_size;
-  uint64_t data_size;
+  uint32_t headers_bytes, num_channels, comments_bytes;
+  uint64_t num_samples;
   double   rate;
-  uint32_t channels;
 
-  if (lsx_readchars(ft, magic_, sizeof(magic)))
+  if (lsx_readdw(ft, (uint32_t *)&magic_))
     return SOX_EOF;
 
   if (memcmp(magic, magic_, sizeof(magic))) {
-    lsx_fail_errno(ft, SOX_EHDR, "can't find sox file format identifier");
-    return SOX_EOF;
+    if (memcmp(cigam, magic_, sizeof(magic))) {
+      lsx_fail_errno(ft, SOX_EHDR, "can't find sox file format identifier");
+      return SOX_EOF;
+    }
+    ft->encoding.reverse_bytes = !ft->encoding.reverse_bytes;
+    lsx_report("file is opposite endian");
   }
-  if (lsx_readdw(ft, &hdr_size) ||
-      lsx_readqw(ft, &data_size) ||
+  if (lsx_readdw(ft, &headers_bytes) ||
+      lsx_readqw(ft, &num_samples) ||
       lsx_readdf(ft, &rate) ||
-      lsx_readdw(ft, &channels))
+      lsx_readdw(ft, &num_channels) ||
+      lsx_readdw(ft, &comments_bytes))
     return SOX_EOF;
 
-  if (hdr_size < FIXED_HDR) {
-    lsx_fail_errno(ft, SOX_EHDR, "header size %u is too small", hdr_size);
+  if (((headers_bytes + 4) & 7) || headers_bytes < FIXED_HDR + comments_bytes) {
+    lsx_fail_errno(ft, SOX_EHDR, "invalid sox file format header");
     return SOX_EOF;
   }
 
-  if (hdr_size > FIXED_HDR) {
-    size_t info_size = hdr_size - FIXED_HDR;
-    char * buf = lsx_calloc(1, info_size + 1); /* +1 ensures null-terminated */
-    if (lsx_readchars(ft, buf, info_size) != SOX_SUCCESS) {
+  if (comments_bytes) {
+    char * buf = lsx_calloc(1, comments_bytes + 1); /* ensure nul-terminated */
+    if (lsx_readchars(ft, buf, comments_bytes) != SOX_SUCCESS) {
       free(buf);
       return SOX_EOF;
     }
@@ -57,25 +61,27 @@
     sox_append_comments(&ft->oob.comments, buf);
     free(buf);
   }
+  lsx_seeki(ft, (off_t)(headers_bytes - FIXED_HDR - comments_bytes), SEEK_CUR);
   return lsx_check_read_params(
-      ft, channels, rate, SOX_ENCODING_SIGN2, 32, (off_t)data_size);
+      ft, num_channels, rate, SOX_ENCODING_SIGN2, 32, (off_t)num_samples);
 }
 
 static int write_header(sox_format_t * ft)
 {
-  char * comment  = lsx_cat_comments(ft->oob.comments);
-  size_t len      = strlen(comment) + 1;     /* Write out null-terminated */
-  size_t info_len = max(4, (len + 3) & ~3u); /* Minimum & multiple of 4 bytes */
+  char * comments  = lsx_cat_comments(ft->oob.comments);
+  size_t comments_len = strlen(comments);
+  size_t comments_bytes = (comments_len + 7) & ~7u; /* Multiple of 8 bytes */
   uint64_t size   = ft->olength? ft->olength : ft->signal.length;
   sox_bool error  = sox_false
-  ||lsx_writechars(ft, magic, sizeof(magic))
-  ||lsx_writedw(ft, FIXED_HDR + (unsigned)info_len)
+  ||lsx_writedw(ft, *(uint32_t *)&magic)
+  ||lsx_writedw(ft, FIXED_HDR + (unsigned)comments_bytes)
   ||lsx_writeqw(ft, size)
   ||lsx_writedf(ft, ft->signal.rate)
   ||lsx_writedw(ft, ft->signal.channels)
-  ||lsx_writechars(ft, comment, len)
-  ||lsx_padbytes(ft, info_len - len);
-  free(comment);
+  ||lsx_writedw(ft, comments_len)
+  ||lsx_writechars(ft, comments, comments_len)
+  ||lsx_padbytes(ft, comments_bytes - comments_len);
+  free(comments);
   return error? SOX_EOF: SOX_SUCCESS;
 }
 
@@ -84,7 +90,7 @@
   static char const * const names[] = {"sox", NULL};
   static unsigned const write_encodings[] = {SOX_ENCODING_SIGN2, 32, 0, 0};
   static sox_format_handler_t const handler = {SOX_LIB_VERSION_CODE,
-    "SoX temporary", names, SOX_FILE_REWIND, startread, lsx_rawread, NULL,
+    "SoX native", names, SOX_FILE_REWIND, startread, lsx_rawread, NULL,
     write_header, lsx_rawwrite, NULL, lsx_rawseek, write_encodings, NULL, 0
   };
   return &handler;