From 015998d3a45137d021ffb22c71c1dd8fb80767b0 Mon Sep 17 00:00:00 2001 From: "sgunderson@bigfoot.com" <> Date: Thu, 28 Dec 2006 19:55:29 +0100 Subject: [PATCH] Change from sine to square triggering. --- estimate-skew.c | 90 --------------------- estimate-skew.cpp | 199 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 199 insertions(+), 90 deletions(-) delete mode 100644 estimate-skew.c create mode 100644 estimate-skew.cpp diff --git a/estimate-skew.c b/estimate-skew.c deleted file mode 100644 index e8ba75e..0000000 --- a/estimate-skew.c +++ /dev/null @@ -1,90 +0,0 @@ -#include -#include -#include -#include - -double frac(double x) -{ - return x - (int)x; -} - -double filter(double x) -{ - static double l = 0.0; - l = 0.001 * x + 0.999 * l; - return l; -} - -int main(int argc, char **argv) -{ - FILE *in1, *in2, *skew; - - // open input1 (reference) - if (strcmp(argv[1], "-") == 0) { - in1 = stdin; - } else { - in1 = fopen(argv[1], "rb"); - if (in1 == NULL) { - perror(argv[1]); - exit(1); - } - } - - // open input2 - if (strcmp(argv[2], "-") == 0) { - in2 = stdin; - } else { - in2 = fopen(argv[2], "rb"); - if (in2 == NULL) { - perror(argv[2]); - exit(1); - } - } - - // open (estimated) skew - if (strcmp(argv[3], "-") == 0) { - skew = stderr; - } else { - skew = fopen(argv[3], "wb"); - if (skew == NULL) { - perror(argv[3]); - exit(1); - } - } - - short prev_sample, sample = 0; - int in_pos = -1; - double p = 0.0; - double speed = 1.001; - - while (!feof(in1) && !feof(in2)) { - short refs; - - // read sample from reference - if (fread(&refs, sizeof(short), 1, in1) != 1) { - exit(0); - } - - // read sample from in2 (at current speed) - p += speed; - while ((int)(ceil(p)) > in_pos) { - prev_sample = sample; - if (fread(&sample, sizeof(short), 1, in2) != 1) { - exit(0); - } - ++in_pos; - } - - // linear interpolation (works well since delta_p varies so slowly) - double t = frac(p); - double intp_sample = prev_sample * (1.0 - t) + sample * t; - - // subtract the two samples and pull it through a filter. we assume - // the sines are normalized for now (and that there's no dc skew) - double offset = filter(intp_sample - refs); - speed += 1e-8 * offset; - fwrite(&speed, sizeof(double), 1, skew); - - printf("%f (offset=%f / filt=%f)\n", speed, intp_sample - refs, offset); - } -} diff --git a/estimate-skew.cpp b/estimate-skew.cpp new file mode 100644 index 0000000..f129c49 --- /dev/null +++ b/estimate-skew.cpp @@ -0,0 +1,199 @@ +#include +#include +#include +#include + +double frac(double x) +{ + return x - (int)x; +} + +class FlankDetector +{ +private: + static const unsigned NUM_SAMPLES = 10; + static const int MIN_LEVEL = 8192; + + bool status, flag; // high/low + unsigned counter; + +public: + FlankDetector() : status(false), flag(false), counter(0) {} + void update(short x) + { + if (abs(x) < MIN_LEVEL) { + counter = 0; + return; + } + + if (!status) { + // low + if (x >= MIN_LEVEL) { + ++counter; + } else { + counter = 0; + } + } else { + // high + if (x <= -MIN_LEVEL) { + ++counter; + } else { + counter = 0; + } + } + + if (counter >= NUM_SAMPLES) { + status = !status; + counter = 0; + flag = true; + } + } + + bool check_flag() + { + bool ret = flag; + flag = false; + return ret; + } + + bool get_status() const + { + return status; + } +}; + +class InterpolatingReader +{ +private: + FILE *f; + double speed; + double p; + int in_pos; + short prev_sample; + +public: + InterpolatingReader(FILE *f) : f(f), speed(1.0), p(0.0), in_pos(-1) {} + + void update_speed(double speed) + { + this->speed = speed; + } + + double read_sample() + { + short sample; + + p += speed; + while ((int)(ceil(p)) > in_pos) { + prev_sample = sample; + if (fread(&sample, sizeof(short), 1, f) != 1) { + exit(0); + } + ++in_pos; + } + + // linear interpolation (works OK since delta_p varies so slowly) + double t = frac(p); + return prev_sample * (1.0 - t) + sample * t; + } +}; + +double filter(double x) +{ + static double l = 1.0; + l = 0.01 * x + 0.99 * l; + return l; +} + +int main(int argc, char **argv) +{ + FILE *in1, *in2, *skew; + + // open input1 (reference) + if (strcmp(argv[1], "-") == 0) { + in1 = stdin; + } else { + in1 = fopen(argv[1], "rb"); + if (in1 == NULL) { + perror(argv[1]); + exit(1); + } + } + + // open input2 + if (strcmp(argv[2], "-") == 0) { + in2 = stdin; + } else { + in2 = fopen(argv[2], "rb"); + if (in2 == NULL) { + perror(argv[2]); + exit(1); + } + } + + // open (estimated) skew + if (strcmp(argv[3], "-") == 0) { + skew = stderr; + } else { + skew = fopen(argv[3], "wb"); + if (skew == NULL) { + perror(argv[3]); + exit(1); + } + } + + FlankDetector f1, f2; + + // initial sync, reference + do { + short s; + if (fread(&s, sizeof(short), 1, in1) != 1) { + exit(0); + } + + f1.update(s); + } while (!f1.check_flag() || !f1.get_status()); + + // initial sync, input + do { + short s; + if (fread(&s, sizeof(short), 1, in2) != 1) { + exit(0); + } + + f2.update(s); + } while (!f2.check_flag() || !f2.get_status()); + + double speed = 1.000; + + InterpolatingReader intp(in2); + intp.update_speed(speed); // test to see if we can resync OK + + while (!feof(in1) && !feof(in2)) { + short refs; + + // read reference until the next triggering + unsigned num_ref = 0; + while (!feof(in1) && !f1.check_flag()) { + if (fread(&refs, sizeof(short), 1, in1) != 1) { + exit(0); + } + f1.update(refs); + ++num_ref; + } + + // same here + unsigned num_inp = 0; + while (!feof(in2) && !f2.check_flag()) { + double s = intp.read_sample(); + f2.update((short)s); + ++num_inp; + } + + double ns = filter(speed * double(num_inp) / double(num_ref)); + printf("%u vs. %u -- ratio %f, speed %f, filtered speed %f\n", num_inp, num_ref, + double(num_inp) / double(num_ref), speed * double(num_inp) / double(num_ref), ns); + speed = ns; + intp.update_speed(ns); + } +} -- 2.39.2