X-Git-Url: https://git.sesse.net/?p=c64tapwav;a=blobdiff_plain;f=decode.c;h=e20c8c9d39743f3b0c011fe1d25bc754f81f9152;hp=7e4c84b182bcea56530cda7bedcb9c3e334e3dd0;hb=e3e486002a6873305b9e858126fe5119e2e4077d;hpb=64f186d68c59fe7cd21fa02fa5f910f60644b8a7 diff --git a/decode.c b/decode.c index 7e4c84b..e20c8c9 100644 --- a/decode.c +++ b/decode.c @@ -2,10 +2,12 @@ #include #include #include +#include #include #define LANCZOS_RADIUS 30 -#define LEN 813440 +#define BUFSIZE 4096 +#define HYSTERESIS_LIMIT 1000 double sinc(double x) { @@ -34,38 +36,36 @@ double weight(double x) } #endif -double interpolate(const short *in, double i) +double interpolate(const std::vector &pcm, double i) { - int lower = std::max(int(ceil(i - LANCZOS_RADIUS)), 0); - int upper = std::min(int(floor(i + LANCZOS_RADIUS)), LEN - 1); + 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 += in[x] * weight(i - x); + sum += pcm[x] * weight(i - x); } return sum; } -short in[LEN]; - // between [x,x+1] -double find_zerocrossing(int x) +double find_zerocrossing(const std::vector &pcm, int x) { - if (in[x] == 0) { + if (pcm[x] == 0) { return x; } - if (in[x + 1] == 0) { + if (pcm[x + 1] == 0) { return x + 1; } - assert(in[x + 1] > 0); - assert(in[x] < 0); + assert(pcm[x + 1] > 0); + assert(pcm[x] < 0); double lower = x; double upper = x + 1; while (upper - lower > 1e-6) { double mid = 0.5f * (upper + lower); - if (interpolate(in, mid) > 0) { + if (interpolate(pcm, mid) > 0) { upper = mid; } else { lower = mid; @@ -77,7 +77,15 @@ double find_zerocrossing(int x) int main(int argc, char **argv) { - fread(in, LEN*2, 1, stdin); + std::vector pcm; + + while (!feof(stdin)) { + short buf[BUFSIZE]; + ssize_t ret = fread(buf, 2, BUFSIZE, stdin); + if (ret >= 0) { + pcm.insert(pcm.end(), buf, buf + ret); + } + } #if 0 for (int i = 0; i < LEN; ++i) { @@ -92,18 +100,21 @@ int main(int argc, char **argv) #endif int last_bit = -1; double last_upflank = -1; - for (int i = 0; i < LEN; ++i) { - int bit = (in[i] > 0) ? 1 : 0; - if (bit == 1 && last_bit == 0) { + int last_max_level = 0; + for (int i = 0; i < pcm.size(); ++i) { + int bit = (pcm[i] > 0) ? 1 : 0; + if (bit == 1 && last_bit == 0 && last_max_level > HYSTERESIS_LIMIT) { // up-flank! - double t = find_zerocrossing(i - 1) * (123156.0/44100.0); + double t = find_zerocrossing(pcm, i - 1) * (123156.0/44100.0); if (last_upflank > 0) { // fprintf(stderr, "length: %f (0x%x)\n", t - last_upflank, lrintf(t - last_upflank)); int len = lrintf(t - last_upflank); printf("0x%x\n", len); } last_upflank = t; + last_max_level = 0; } + last_max_level = std::max(last_max_level, abs(pcm[i])); last_bit = bit; } }