sox.1: fix example for mcompand
[sox.git] / src / cvsd-fmt.c
blob4d42aa71b028d580ae900176cefb35d7d51f272a
1 /* libSoX file format: CVSD (see cvsd.c) (c) 2007-8 SoX contributors
3 * This library is free software; you can redistribute it and/or modify it
4 * under the terms of the GNU Lesser General Public License as published by
5 * the Free Software Foundation; either version 2.1 of the License, or (at
6 * your option) any later version.
8 * This library is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
11 * General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this library; if not, write to the Free Software Foundation,
15 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 #include "cvsd.h"
20 LSX_FORMAT_HANDLER(cvsd)
22 static char const * const names[] = {"cvsd", "cvs", NULL};
23 static unsigned const write_encodings[] = {SOX_ENCODING_CVSD, 1, 0, 0};
24 static sox_format_handler_t const handler = {SOX_LIB_VERSION_CODE,
25 "Headerless MIL Std 188 113 Continuously Variable Slope Delta modulation",
26 names, SOX_FILE_MONO,
27 lsx_cvsdstartread, lsx_cvsdread, lsx_cvsdstopread,
28 lsx_cvsdstartwrite, lsx_cvsdwrite, lsx_cvsdstopwrite,
29 lsx_rawseek, write_encodings, NULL, sizeof(cvsd_priv_t)
31 return &handler;
34 /* libSoX file format: CVU (c) 2008 robs@users.sourceforge.net
35 * Unfiltered, therefore, on decode, use with either filter -4k or rate 8k */
37 typedef struct {
38 double sample, step, step_mult, step_add;
39 unsigned last_n_bits;
40 unsigned char byte;
41 off_t bit_count;
42 } priv_t;
44 static int start(sox_format_t * ft)
46 priv_t *p = (priv_t *) ft->priv;
48 ft->signal.channels = 1;
49 lsx_rawstart(ft, sox_true, sox_false, sox_true, SOX_ENCODING_CVSD, 1);
50 p->last_n_bits = 5; /* 101 */
51 p->step_mult = exp((-1 / .005 / ft->signal.rate));
52 p->step_add = (1 - p->step_mult) * (.1 * SOX_SAMPLE_MAX);
53 lsx_debug("step_mult=%g step_add=%f", p->step_mult, p->step_add);
54 return SOX_SUCCESS;
57 static void decode(priv_t * p, int bit)
59 p->last_n_bits = ((p->last_n_bits << 1) | bit) & 7;
61 p->step *= p->step_mult;
62 if (p->last_n_bits == 0 || p->last_n_bits == 7)
63 p->step += p->step_add;
65 if (p->last_n_bits & 1)
66 p->sample = min(p->step_mult * p->sample + p->step, SOX_SAMPLE_MAX);
67 else
68 p->sample = max(p->step_mult * p->sample - p->step, SOX_SAMPLE_MIN);
71 static size_t cvsdread(sox_format_t * ft, sox_sample_t * buf, size_t len)
73 priv_t *p = (priv_t *) ft->priv;
74 size_t i;
76 for (i = 0; i < len; ++i) {
77 if (!(p->bit_count & 7))
78 if (lsx_read_b_buf(ft, &p->byte, (size_t)1) != 1)
79 break;
80 ++p->bit_count;
81 decode(p, p->byte & 1);
82 p->byte >>= 1;
83 *buf++ = floor(p->sample + .5);
85 return i;
88 static size_t cvsdwrite(sox_format_t * ft, sox_sample_t const * buf, size_t len)
90 priv_t *p = (priv_t *) ft->priv;
91 size_t i;
93 for (i = 0; i < len; ++i) {
94 decode(p, *buf++ > p->sample);
95 p->byte >>= 1;
96 p->byte |= p->last_n_bits << 7;
97 if (!(++p->bit_count & 7))
98 if (lsx_writeb(ft, p->byte) != SOX_SUCCESS)
99 break;
101 return len;
104 LSX_FORMAT_HANDLER(cvu)
106 static char const * const names[] = {"cvu", NULL};
107 static unsigned const write_encodings[] = {SOX_ENCODING_CVSD, 1, 0, 0};
108 static sox_format_handler_t const handler = {SOX_LIB_VERSION_CODE,
109 "Headerless Continuously Variable Slope Delta modulation (unfiltered)",
110 names, SOX_FILE_MONO, start, cvsdread, NULL, start, cvsdwrite, NULL,
111 lsx_rawseek, write_encodings, NULL, sizeof(priv_t)
113 return &handler;