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)