From: Steinar H. Gunderson Date: Sat, 4 May 2013 20:44:22 +0000 (+0200) Subject: Add table-based lookups for the Lanczos interpolation, and use that in the syncer. X-Git-Url: https://git.sesse.net/?p=c64tapwav;a=commitdiff_plain;h=08089f496815d725c3bee171bae0e884642ffc05 Add table-based lookups for the Lanczos interpolation, and use that in the syncer. --- diff --git a/Makefile b/Makefile index 03d97ff..ae22aa8 100644 --- a/Makefile +++ b/Makefile @@ -5,18 +5,18 @@ all: synth decode sync %.o: %.cpp $(CXX) -MMD -MP $(CPPFLAGS) $(CXXFLAGS) -o $@ -c $< -OBJS=decode.o synth.o synth_main.o +OBJS=decode.o synth.o synth_main.o interpolate.o sync.o DEPS=$(OBJS:.o=.d) -include $(DEPS) -decode: decode.o +decode: interpolate.o decode.o $(CXX) -o $@ $^ $(LDFLAGS) synth: synth.o synth_main.o $(CXX) -o $@ $^ $(LDFLAGS) -sync: sync.o +sync: interpolate.o sync.o $(CXX) -o $@ $^ $(LDFLAGS) clean: diff --git a/decode.cpp b/decode.cpp index fdc1347..99776bc 100644 --- a/decode.cpp +++ b/decode.cpp @@ -61,6 +61,7 @@ struct pulse { int main(int argc, char **argv) { + make_lanczos_weight_table(); std::vector pcm; while (!feof(stdin)) { diff --git a/interpolate.cpp b/interpolate.cpp new file mode 100644 index 0000000..cd250c1 --- /dev/null +++ b/interpolate.cpp @@ -0,0 +1,11 @@ +#include "interpolate.h" + +double lanczos_table[(LANCZOS_RADIUS * 2) * LANCZOS_RESOLUTION]; + +void make_lanczos_weight_table() +{ + for (int i = 0; i < (LANCZOS_RADIUS * 2) * LANCZOS_RESOLUTION; ++i) { + float x = double(i) / LANCZOS_RESOLUTION - LANCZOS_RADIUS; + lanczos_table[i] = lanczos_weight(x); + } +} diff --git a/interpolate.h b/interpolate.h index 2b4842a..55bc61c 100644 --- a/interpolate.h +++ b/interpolate.h @@ -7,6 +7,7 @@ #include #define LANCZOS_RADIUS 30 +#define LANCZOS_RESOLUTION 256 inline double sinc(double x) { @@ -25,6 +26,18 @@ inline double lanczos_weight(double x) return sinc(M_PI * x) * sinc(M_PI * x / LANCZOS_RADIUS); } +extern double lanczos_table[(LANCZOS_RADIUS * 2) * LANCZOS_RESOLUTION]; +void make_lanczos_weight_table(); + +inline double lanczos_weight_table(double x) +{ + int table_id = lrintf((x + LANCZOS_RADIUS) * LANCZOS_RESOLUTION); + if (table_id < 0 || table_id >= (LANCZOS_RADIUS * 2) * LANCZOS_RESOLUTION) { + return 0.0; + } + return lanczos_table[table_id]; +} + template inline double lanczos_interpolate(const std::vector &pcm, double i) { @@ -33,7 +46,7 @@ inline double lanczos_interpolate(const std::vector &pcm, double i) double sum = 0.0f; for (int x = lower; x <= upper; ++x) { - sum += pcm[x] * lanczos_weight(i - x); + sum += pcm[x] * lanczos_weight_table(i - x); } return sum; } @@ -46,7 +59,7 @@ inline double lanczos_interpolate_right(const std::vector &pcm, double i) double sum = 0.0f; for (int x = lower; x <= upper; ++x) { - sum += pcm[x].right * lanczos_weight(i - x); + sum += pcm[x].right * lanczos_weight_table(i - x); } return sum; } diff --git a/sync.cpp b/sync.cpp index 7e43ec1..d291808 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 @@ -41,6 +41,7 @@ struct hypothesis { int main(int argc, char **argv) { + make_lanczos_weight_table(); std::vector pcm; while (!feof(stdin)) { @@ -113,7 +114,7 @@ int main(int argc, char **argv) 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, "\b\b\b\b\b\b\b%7.2f", i / 44100.0); size_t end = std::min(i + BUFSIZE, total_end); @@ -182,9 +183,9 @@ int main(int argc, char **argv) std::vector aligned_pcm; std::vector mono_pcm; for (unsigned i = 0; i < total_end; ++i) { - double d = linear_interpolate(best_path, i / double(BUFSIZE)); + double d = lanczos_interpolate(best_path, i / double(BUFSIZE)); int left = pcm[i].left; - int right = linear_interpolate_right(pcm, i + d); + int right = lanczos_interpolate_right(pcm, i + d); stereo_sample ss; ss.left = left;