From c9c94ca1c247adfc1a78fda0eda185a9a7589696 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Fri, 14 Dec 2012 16:18:47 +0000 Subject: merge robin gareus' libltc into ardour source tree for convenience git-svn-id: svn://localhost/ardour2/branches/3.0@13665 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/libltc/encoder.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 libs/libltc/encoder.c (limited to 'libs/libltc/encoder.c') diff --git a/libs/libltc/encoder.c b/libs/libltc/encoder.c new file mode 100644 index 0000000000..fce2a0ce51 --- /dev/null +++ b/libs/libltc/encoder.c @@ -0,0 +1,106 @@ +/* + libltc - en+decode linear timecode + + Copyright (C) 2006-2012 Robin Gareus + + This program 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 3 of the + License, or (at your option) any later version. + + This program 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, see . +*/ + +#include +#include +#include +#include + +#include "ltc/encoder.h" + +/** + * add values to the output buffer + */ +static int addvalues(LTCEncoder *e, int n) { + const ltcsnd_sample_t tgtval = e->state ? e->enc_hi : e->enc_lo; + + if (e->offset + n >= e->bufsize) { + fprintf(stderr, "libltc: buffer overflow: %d/%lu\n", (int) e->offset, (unsigned long) e->bufsize); + return 1; + } + + ltcsnd_sample_t * const wave = &(e->buf[e->offset]); + const double tcf = e->filter_const; + if (tcf > 0) { + /* low-pass-filter + * LTC signal should have a rise time of 40 us +/- 10 us. + * + * rise-time means from <10% to >90% of the signal. + * in each call to addvalues() we start at 50%, so + * here we need half-of it. (0.000020 sec) + * + * e->cutoff = 1.0 -exp( -1.0 / (sample_rate * .000020 / exp(1.0)) ); + */ + int i; + ltcsnd_sample_t val = SAMPLE_CENTER; + int m = (n+1)>>1; + for (i = 0 ; i < m ; i++) { + val = val + tcf * (tgtval - val); + wave[n-i-1] = wave[i] = val; + } + } else { + /* perfect square wave */ + memset(wave, tgtval, n); + } + + e->offset += n; + return 0; +} + +int encode_byte(LTCEncoder *e, int byte, double speed) { + if (byte < 0 || byte > 9) return -1; + if (speed ==0) return -1; + + int err = 0; + const unsigned char c = ((unsigned char*)&e->f)[byte]; + unsigned char b = (speed < 0)?128:1; // bit + const double spc = e->samples_per_clock * fabs(speed); + const double sph = e->samples_per_clock_2 * fabs(speed); + + do + { + int n; + if ((c & b) == 0) { + n = (int)(spc + e->sample_remainder); + e->sample_remainder = spc + e->sample_remainder - n; + e->state = !e->state; + err |= addvalues(e, n); + } else { + n = (int)(sph + e->sample_remainder); + e->sample_remainder = sph + e->sample_remainder - n; + e->state = !e->state; + err |= addvalues(e, n); + + n = (int)(sph + e->sample_remainder); + e->sample_remainder = sph + e->sample_remainder - n; + e->state = !e->state; + err |= addvalues(e, n); + } + /* this is based on the assumption that with every compiler + * ((unsigned char) 128)<<1 == ((unsigned char 1)>>1) == 0 + */ + if (speed < 0) + b >>= 1; + else + b <<= 1; + } while (b); + + return err; +} -- cgit v1.2.3