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
|
/*
* Copyright (C) 2010 Mark Hills <mark@pogo.org.uk>
*
* 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 "device.h"
#include "lut.h"
#include "pitch.h"
#define TIMECODER_CHANNELS DEVICE_CHANNELS
typedef unsigned int bits_t;
struct timecode_def_t {
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_t lut;
};
struct timecoder_channel_t {
int 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_t {
struct timecode_def_t *def;
/* Precomputed values */
float dt, zero_alpha;
/* Pitch information */
int forwards;
struct timecoder_channel_t primary, secondary;
struct pitch_t 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;
};
void timecoder_free_lookup(void);
int timecoder_init(struct timecoder_t *tc, const char *def_name,
unsigned int sample_rate);
void timecoder_clear(struct timecoder_t *tc);
int timecoder_monitor_init(struct timecoder_t *tc, int size);
void timecoder_monitor_clear(struct timecoder_t *tc);
void timecoder_submit(struct timecoder_t *tc, signed short *pcm, size_t npcm);
signed int timecoder_get_position(struct timecoder_t *tc, float *when);
/* Return the pitch, based on filtered cycles of the sine wave */
static inline float timecoder_get_pitch(struct timecoder_t *tc)
{
return pitch_current(&tc->pitch);
}
/* 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_t *tc)
{
return tc->def->safe;
}
/* The resolution of the timecode. This is the number of bits per
* second, which corresponds to the frequency of the sine wave */
static inline int timecoder_get_resolution(struct timecoder_t *tc)
{
return tc->def->resolution;
}
#endif
|