1 /*
2    libltc - en+decode linear timecode
3 
4    Copyright (C) 2006-2012 Robin Gareus <robin@gareus.org>
5 
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU Lesser General Public License as
8    published by the Free Software Foundation, either version 3 of the
9    License, or (at your option) any later version.
10 
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU Lesser General Public License for more details.
15 
16    You should have received a copy of the GNU Lesser General Public
17    License along with this library.
18    If not, see <http://www.gnu.org/licenses/>.
19 */
20 
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <math.h>
25 
26 #include "encoder.h"
27 
28 /**
29  * add values to the output buffer
30  */
addvalues(LTCEncoder * e,int n)31 static int addvalues(LTCEncoder *e, int n) {
32 	const ltcsnd_sample_t tgtval = e->state ? e->enc_hi : e->enc_lo;
33 
34 	if (e->offset + n >= e->bufsize) {
35 #if 0
36 		fprintf(stderr, "libltc: buffer overflow: %d/%lu\n", (int) e->offset, (unsigned long) e->bufsize);
37 #endif
38 		return 1;
39 	}
40 
41 	ltcsnd_sample_t * const wave = &(e->buf[e->offset]);
42 	const double tcf =  e->filter_const;
43 	if (tcf > 0) {
44 		/* low-pass-filter
45 		 * LTC signal should have a rise time of 40 us +/- 10 us.
46 		 *
47 		 * rise-time means from <10% to >90% of the signal.
48 		 * in each call to addvalues() we start at 50%, so
49 		 * here we need half-of it. (0.000020 sec)
50 		 *
51 		 * e->cutoff = 1.0 -exp( -1.0 / (sample_rate * .000020 / exp(1.0)) );
52 		 */
53 		int i;
54 		ltcsnd_sample_t val = SAMPLE_CENTER;
55 		int m = (n+1)>>1;
56 		for (i = 0 ; i < m ; i++) {
57 			val = val + tcf * (tgtval - val);
58 			wave[n-i-1] = wave[i] = val;
59 		}
60 	} else {
61 		/* perfect square wave */
62 		memset(wave, tgtval, n);
63 	}
64 
65 	e->offset += n;
66 	return 0;
67 }
68 
encode_byte(LTCEncoder * e,int byte,double speed)69 int encode_byte(LTCEncoder *e, int byte, double speed) {
70 	if (byte < 0 || byte > 9) return -1;
71 	if (speed ==0) return -1;
72 
73 	int err = 0;
74 	const unsigned char c = ((unsigned char*)&e->f)[byte];
75 	unsigned char b = (speed < 0)?128:1; // bit
76 	const double spc = e->samples_per_clock * fabs(speed);
77 	const double sph = e->samples_per_clock_2 * fabs(speed);
78 
79 	do
80 	{
81 		int n;
82 		if ((c & b) == 0) {
83 			n = (int)(spc + e->sample_remainder);
84 			e->sample_remainder = spc + e->sample_remainder - n;
85 			e->state = !e->state;
86 			err |= addvalues(e, n);
87 		} else {
88 			n = (int)(sph + e->sample_remainder);
89 			e->sample_remainder = sph + e->sample_remainder - n;
90 			e->state = !e->state;
91 			err |= addvalues(e, n);
92 
93 			n = (int)(sph + e->sample_remainder);
94 			e->sample_remainder = sph + e->sample_remainder - n;
95 			e->state = !e->state;
96 			err |= addvalues(e, n);
97 		}
98 		/* this is based on the assumption that with every compiler
99 		 * ((unsigned char) 128)<<1 == ((unsigned char 1)>>1) == 0
100 		 */
101 		if (speed < 0)
102 			b >>= 1;
103 		else
104 			b <<= 1;
105 	} while (b);
106 
107 	return err;
108 }
109