shithub: sox

Download patch

ref: 693c66a968b6d615854dcb37dfee327079ee66e6
parent: 1139f212c5ec622ebd44fffa970ebede56e36960
author: robs <robs>
date: Thu Sep 25 11:49:28 EDT 2008

unfiltered cvsd

--- a/src/cvsd-fmt.c
+++ b/src/cvsd-fmt.c
@@ -22,11 +22,93 @@
   static char const * const names[] = {"cvsd", "cvs", NULL};
   static unsigned const write_encodings[] = {SOX_ENCODING_CVSD, 1, 0, 0};
   static sox_format_handler_t const handler = {SOX_LIB_VERSION_CODE,
-    "Headerless Continuously Variable Slope Delta modulation",
+    "Headerless MIL Std 188 113 Continuously Variable Slope Delta modulation",
     names, SOX_FILE_MONO,
     sox_cvsdstartread, sox_cvsdread, sox_cvsdstopread,
     sox_cvsdstartwrite, sox_cvsdwrite, sox_cvsdstopwrite,
     lsx_rawseek, write_encodings, NULL, sizeof(cvsd_priv_t)
+  };
+  return &handler;
+}
+
+/* libSoX file format: CVU   (c) 2008 robs@users.sourceforge.net
+ * Unfiltered, therefore, on decode, use with either filter -4k or rate 8k */
+
+typedef struct {
+  double         sample, step, step_mult, step_add;
+  unsigned       last_n_bits;
+  unsigned char  byte;
+  off_t          bit_count;
+} priv_t;
+
+static int start(sox_format_t * ft)
+{
+  priv_t *p = (priv_t *) ft->priv;
+
+  ft->signal.channels = 1;
+  lsx_rawstart(ft, sox_true, sox_false, sox_true, SOX_ENCODING_CVSD, 1);
+  p->last_n_bits = 5; /* 101 */
+  p->step_mult = exp((-1 / .005 / ft->signal.rate));
+  p->step_add = (1 - p->step_mult) * (.1 * SOX_SAMPLE_MAX);
+  sox_debug("step_mult=%g step_add=%f", p->step_mult, p->step_add);
+  return SOX_SUCCESS;
+}
+
+static void decode(priv_t * p, int bit)
+{
+  p->last_n_bits = ((p->last_n_bits << 1) | bit) & 7;
+
+  p->step *= p->step_mult;
+  if (p->last_n_bits == 0 || p->last_n_bits == 7)
+    p->step += p->step_add;
+
+  if (p->last_n_bits & 1)
+    p->sample = min(p->step_mult * p->sample + p->step, SOX_SAMPLE_MAX);
+  else
+    p->sample = max(p->step_mult * p->sample - p->step, SOX_SAMPLE_MIN);
+}
+
+static size_t read(sox_format_t * ft, sox_sample_t * buf, size_t len)
+{
+  priv_t *p = (priv_t *) ft->priv;
+  size_t i;
+
+  for (i = 0; i < len; ++i) {
+    if (!(p->bit_count & 7))
+      if (lsx_read_b_buf(ft, &p->byte, 1) != 1)
+        break;
+    ++p->bit_count;
+    decode(p, p->byte & 1);
+    p->byte >>= 1;
+    *buf++ = floor(p->sample + .5);
+  }
+  return i;
+}
+
+static size_t write(sox_format_t * ft, sox_sample_t const * buf, size_t len)
+{
+  priv_t *p = (priv_t *) ft->priv;
+  size_t i;
+
+  for (i = 0; i < len; ++i) {
+    decode(p, *buf++ > p->sample);
+    p->byte >>= 1;
+    p->byte |= p->last_n_bits << 7;
+    if (!(++p->bit_count & 7))
+      if (lsx_writeb(ft, p->byte) != SOX_SUCCESS)
+        break;
+  }
+  return len;
+}
+
+SOX_FORMAT_HANDLER(cvu)
+{
+  static char const * const names[] = {"cvu", NULL};
+  static unsigned const write_encodings[] = {SOX_ENCODING_CVSD, 1, 0, 0};
+  static sox_format_handler_t const handler = {SOX_LIB_VERSION_CODE,
+    "Headerless Continuously Variable Slope Delta modulation (unfiltered)",
+    names, SOX_FILE_MONO, start, read, NULL, start, write, NULL,
+    lsx_rawseek, write_encodings, NULL, sizeof(priv_t)
   };
   return &handler;
 }
--- a/src/dvms-fmt.c
+++ b/src/dvms-fmt.c
@@ -22,7 +22,7 @@
   static char const * const names[] = {"dvms", "vms", NULL};
   static unsigned const write_encodings[] = {SOX_ENCODING_CVSD, 1, 0, 0};
   static sox_format_handler_t const handler = {SOX_LIB_VERSION_CODE,
-    "Continuously Variable Slope Delta modulation with header",
+    "MIL Std 188 113 Continuously Variable Slope Delta modulation with header",
     names, SOX_FILE_MONO,
     sox_dvmsstartread, sox_cvsdread, sox_cvsdstopread,
     sox_dvmsstartwrite, sox_cvsdwrite, sox_dvmsstopwrite,
--- a/src/formats.h
+++ b/src/formats.h
@@ -24,6 +24,7 @@
   FORMAT(avr)
   FORMAT(cdr)
   FORMAT(cvsd)
+  FORMAT(cvu)
   FORMAT(dat)
   FORMAT(dvms)
   FORMAT(f4)