Add table-based lookups for the Lanczos interpolation, and use that in the syncer.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Sat, 4 May 2013 20:44:22 +0000 (22:44 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Sat, 4 May 2013 20:44:22 +0000 (22:44 +0200)
Makefile
decode.cpp
interpolate.cpp [new file with mode: 0644]
interpolate.h
sync.cpp

index 03d97ff..ae22aa8 100644 (file)
--- 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:
index fdc1347..99776bc 100644 (file)
@@ -61,6 +61,7 @@ struct pulse {
        
 int main(int argc, char **argv)
 {
+       make_lanczos_weight_table();
        std::vector<short> pcm;
 
        while (!feof(stdin)) {
diff --git a/interpolate.cpp b/interpolate.cpp
new file mode 100644 (file)
index 0000000..cd250c1
--- /dev/null
@@ -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);
+       }
+}
index 2b4842a..55bc61c 100644 (file)
@@ -7,6 +7,7 @@
 #include <vector>
 
 #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<class T>
 inline double lanczos_interpolate(const std::vector<T> &pcm, double i)
 {
@@ -33,7 +46,7 @@ inline double lanczos_interpolate(const std::vector<T> &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<T> &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;
 }
index 7e43ec1..d291808 100644 (file)
--- 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 <stdio.h>
@@ -41,6 +41,7 @@ struct hypothesis {
 
 int main(int argc, char **argv)
 {
+       make_lanczos_weight_table();
        std::vector<stereo_sample> 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<size_t>(i + BUFSIZE, total_end);
@@ -182,9 +183,9 @@ int main(int argc, char **argv)
        std::vector<stereo_sample> aligned_pcm;
        std::vector<short> 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;