X-Git-Url: https://git.sesse.net/?p=c64tapwav;a=blobdiff_plain;f=sync.cpp;h=3acd2016bf9e9ff86cc2a0cfd69a64374d167ebf;hp=4709b84271a2dde47ceed5326c2b037b6d7f82ad;hb=866751f2909657ee7d62f936e3d2cb2ecb7806fb;hpb=9e9da751d8df66b61d930cdf643c65c61ebb4f8a diff --git a/sync.cpp b/sync.cpp index 4709b84..3acd201 100644 --- a/sync.cpp +++ b/sync.cpp @@ -2,8 +2,8 @@ // to find the most likely misalignment as it changes throughout the file. #define NUM_THEORIES 200 -#define THEORY_FROM -10.0 /* in samples */ -#define THEORY_TO 10.0 /* in samples */ +#define THEORY_FROM -20.0 /* in samples */ +#define THEORY_TO 20.0 /* in samples */ #define SWITCH_COST 1000.0 /* pretty arbitrary */ #include @@ -11,14 +11,15 @@ #include #include -#define LANCZOS_RADIUS 30 +#include "interpolate.h" + #define BUFSIZE 4096 struct stereo_sample { short left, right; }; -struct double_stereo_sample { - double left, right; +struct float_stereo_sample { + float left, right; }; inline short clip(int x) @@ -32,68 +33,6 @@ inline short clip(int x) } } -double sinc(double x) -{ - if (fabs(x) < 1e-6) { - return 1.0f - fabs(x); - } else { - return sin(x) / x; - } -} - -#if 0 -double weight(double x) -{ - if (fabs(x) > LANCZOS_RADIUS) { - return 0.0f; - } - return sinc(M_PI * x) * sinc(M_PI * x / LANCZOS_RADIUS); -} - -double interpolate(const std::vector &pcm, double i) -{ - int lower = std::max(ceil(i - LANCZOS_RADIUS), 0); - int upper = std::min(floor(i + LANCZOS_RADIUS), pcm.size() - 1); - double sum = 0.0f; - - for (int x = lower; x <= upper; ++x) { - sum += pcm[x].right * weight(i - x); - } - return sum; -} -#else -double weight(double x) -{ - if (fabs(x) > 1.0f) { - return 0.0f; - } - return 1.0f - fabs(x); -} - -inline double interpolate(const std::vector &pcm, double i) -{ - int ii = int(i); - if (ii < 0 || ii >= int(pcm.size() - 1)) { - return 0.0; - } - double frac = i - ii; - - return pcm[ii] + frac * (pcm[ii + 1] - pcm[ii]); -} - -template -inline double interpolate(const std::vector &pcm, double i) -{ - int ii = int(i); - if (ii < 0 || ii >= int(pcm.size() - 1)) { - return 0.0; - } - double frac = i - ii; - - return pcm[ii].right + frac * (pcm[ii + 1].right - pcm[ii].right); -} -#endif - struct hypothesis { int id; double cost; @@ -102,6 +41,7 @@ struct hypothesis { int main(int argc, char **argv) { + make_lanczos_weight_table(); std::vector pcm; while (!feof(stdin)) { @@ -135,7 +75,7 @@ int main(int argc, char **argv) double inv_sd_left = 1.0 / sqrt(var_left); double inv_sd_right = 1.0 / sqrt(var_right); - std::vector norm; + std::vector norm; norm.resize(pcm.size()); for (unsigned i = 0; i < pcm.size(); ++i) { @@ -162,7 +102,9 @@ int main(int argc, char **argv) #endif double delays[NUM_THEORIES]; + std::vector alloc_hypot; hypothesis *bases = new hypothesis[NUM_THEORIES]; + alloc_hypot.push_back(bases); for (int h = 0; h < NUM_THEORIES; ++h) { delays[h] = THEORY_FROM + h * (THEORY_TO - THEORY_FROM) / (NUM_THEORIES - 1); @@ -171,14 +113,16 @@ int main(int argc, char **argv) bases[h].prev = NULL; } + fprintf(stderr, "Matching blocks... %7.2f", 0.0); hypothesis *prev_hyp = bases; size_t total_end = pcm.size(); - //size_t total_end = 4410000; + //size_t total_end = 441000; for (unsigned i = 0; i < total_end; i += BUFSIZE) { - fprintf(stderr, "%.3f\n", i / 44100.0); + fprintf(stderr, "\b\b\b\b\b\b\b%7.2f", i / 44100.0); size_t end = std::min(i + BUFSIZE, total_end); hypothesis *hyp = new hypothesis[NUM_THEORIES]; + alloc_hypot.push_back(hyp); // evaluate all hypotheses for (int h = 0; h < NUM_THEORIES; ++h) { @@ -186,7 +130,7 @@ int main(int argc, char **argv) double d = delays[h]; for (unsigned s = i; s < end; ++s) { double left = norm[s].left; - double right = interpolate(norm, s + d); + double right = linear_interpolate_right(norm, s + d); double diff = (right - left) * (right - left); sum += diff; } @@ -209,6 +153,7 @@ int main(int argc, char **argv) prev_hyp = hyp; } + fprintf(stderr, "\b\b\b\b\b\b\b%7.2f\n", total_end / 44100.0); // best winner double best_cost = HUGE_VAL; @@ -235,23 +180,34 @@ int main(int argc, char **argv) fprintf(fp, "%f %f\n", i * BUFSIZE / 44100.0, best_path[i]); } fclose(fp); + + // save some RAM + norm = std::vector(); + for (unsigned i = 0; i < alloc_hypot.size(); ++i) { + delete[] alloc_hypot[i]; + } - // readjust and write out + fprintf(stderr, "Stretching right channel to match left... %7.2f%%", 0.0); double inv_sd = sqrt(2.0) / sqrt(var_left + var_right); std::vector aligned_pcm; std::vector mono_pcm; + aligned_pcm.resize(total_end); + mono_pcm.resize(total_end); for (unsigned i = 0; i < total_end; ++i) { - double d = interpolate(best_path, i / double(BUFSIZE)); + double d = lanczos_interpolate(best_path, i / double(BUFSIZE)); int left = pcm[i].left; - int right = interpolate(pcm, i + d); + int right = lanczos_interpolate_right(pcm, i + d); - stereo_sample ss; - ss.left = left; - ss.right = clip(right); - aligned_pcm.push_back(ss); + aligned_pcm[i].left = left; + aligned_pcm[i].right = clip(right); - mono_pcm.push_back(clip(lrintf(inv_sd * 4096.0 * (left + right)))); + mono_pcm[i] = clip(lrintf(inv_sd * 4096.0 * (left + right))); + + if (i % 4096 == 0) { + fprintf(stderr, "\b\b\b\b\b\b\b\b%7.2f%%", 100.0 * i / total_end); + } } + fprintf(stderr, "\b\b\b\b\b\b\b%7.2f%%\n", 100.0); fprintf(stderr, "Writing realigned stereo channels to aligned.raw...\n"); fp = fopen("aligned.raw", "wb");