mirror of
https://github.com/DrBeef/QuestZDoom.git
synced 2025-05-05 07:21:28 +00:00
115 lines
3.6 KiB
C
115 lines
3.6 KiB
C
|
/* libSoX file format: CVSD (see cvsd.c) (c) 2007-8 SoX contributors
|
||
|
*
|
||
|
* 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
|
||
|
* the Free Software Foundation; either version 2.1 of the License, or (at
|
||
|
* your option) any later version.
|
||
|
*
|
||
|
* This library is distributed in the hope that it will be useful, but
|
||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
|
||
|
* General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU Lesser General Public License
|
||
|
* along with this library; if not, write to the Free Software Foundation,
|
||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||
|
*/
|
||
|
|
||
|
#include "cvsd.h"
|
||
|
|
||
|
LSX_FORMAT_HANDLER(cvsd)
|
||
|
{
|
||
|
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 MIL Std 188 113 Continuously Variable Slope Delta modulation",
|
||
|
names, SOX_FILE_MONO,
|
||
|
lsx_cvsdstartread, lsx_cvsdread, lsx_cvsdstopread,
|
||
|
lsx_cvsdstartwrite, lsx_cvsdwrite, lsx_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);
|
||
|
lsx_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 cvsdread(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, (size_t)1) != 1)
|
||
|
break;
|
||
|
++p->bit_count;
|
||
|
decode(p, p->byte & 1);
|
||
|
p->byte >>= 1;
|
||
|
*buf++ = floor(p->sample + .5);
|
||
|
}
|
||
|
return i;
|
||
|
}
|
||
|
|
||
|
static size_t cvsdwrite(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;
|
||
|
}
|
||
|
|
||
|
LSX_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, cvsdread, NULL, start, cvsdwrite, NULL,
|
||
|
lsx_rawseek, write_encodings, NULL, sizeof(priv_t)
|
||
|
};
|
||
|
return &handler;
|
||
|
}
|