-
Notifications
You must be signed in to change notification settings - Fork 0
/
timecoder.h
144 lines (113 loc) · 3.78 KB
/
timecoder.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*
* Copyright (C) 2021 Mark Hills <mark@xwax.org>
*
* This file is part of "xwax".
*
* "xwax" is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License, version 3 as
* published by the Free Software Foundation.
*
* "xwax" 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>.
*
*/
#ifndef TIMECODER_H
#define TIMECODER_H
#include <stdbool.h>
#include "lut.h"
#include "pitch.h"
#define TIMECODER_CHANNELS 2
typedef unsigned int bits_t;
struct timecode_def {
const char *name, *desc;
int bits, /* number of bits in string */
resolution, /* wave cycles per second */
flags;
bits_t seed, /* LFSR value at timecode zero */
taps; /* central LFSR taps, excluding end taps */
unsigned int length, /* in cycles */
safe; /* last 'safe' timecode number (for auto disconnect) */
bool lookup; /* true if lut has been generated */
struct lut lut;
};
struct timecoder_channel {
bool positive, /* wave is in positive part of cycle */
swapped; /* wave recently swapped polarity */
signed int zero;
unsigned int crossing_ticker; /* samples since we last crossed zero */
};
struct timecoder {
struct timecode_def *def;
double speed;
/* Precomputed values */
double dt, zero_alpha;
signed int threshold;
/* Pitch information */
bool forwards;
struct timecoder_channel primary, secondary;
struct pitch pitch;
/* Numerical timecode */
signed int ref_level;
bits_t bitstream, /* actual bits from the record */
timecode; /* corrected timecode */
unsigned int valid_counter, /* number of successful error checks */
timecode_ticker; /* samples since valid timecode was read */
/* Feedback */
unsigned char *mon; /* x-y array */
int mon_size, mon_counter;
};
struct timecode_def* timecoder_find_definition(const char *name);
void timecoder_free_lookup(void);
void timecoder_init(struct timecoder *tc, struct timecode_def *def,
double speed, unsigned int sample_rate, bool phono);
void timecoder_clear(struct timecoder *tc);
int timecoder_monitor_init(struct timecoder *tc, int size);
void timecoder_monitor_clear(struct timecoder *tc);
void timecoder_cycle_definition(struct timecoder *tc);
void timecoder_submit(struct timecoder *tc, signed short *pcm, size_t npcm);
signed int timecoder_get_position(struct timecoder *tc, double *when);
/*
* The timecode definition currently in use by this decoder
*/
static inline struct timecode_def* timecoder_get_definition(struct timecoder *tc)
{
return tc->def;
}
/*
* Return the pitch relative to reference playback speed
*/
static inline double timecoder_get_pitch(struct timecoder *tc)
{
return pitch_current(&tc->pitch) / tc->speed;
}
/*
* The last 'safe' timecode value on the record. Beyond this value, we
* probably want to ignore the timecode values, as we will hit the
* label of the record.
*/
static inline unsigned int timecoder_get_safe(struct timecoder *tc)
{
return tc->def->safe;
}
/*
* The resolution of the timecode. This is the number of bits per
* second at reference playback speed
*/
static inline double timecoder_get_resolution(struct timecoder *tc)
{
return tc->def->resolution * tc->speed;
}
/*
* The number of revolutions per second of the timecode vinyl,
* used only for visual display
*/
static inline double timecoder_revs_per_sec(struct timecoder *tc)
{
return (33.0 + 1.0 / 3) * tc->speed / 60;
}
#endif