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) 2014 Mark Hills <mark@xwax.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2, as published by the Free Software Foundation.
*
* 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
* General Public License version 2 for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
*/
#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 {
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
|