fix Window->Common move for show-mixer
[ardour.git] / libs / libltc / encoder.c
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 "ltc/encoder.h"
27
28 /**
29  * add values to the output buffer
30  */
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
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 }