#include <stdio.h>
#include <string.h>
#include <math.h>
-#include <unistd.h>
#include <assert.h>
+#include <limits.h>
#include <vector>
#include <algorithm>
+#include "audioreader.h"
#include "interpolate.h"
+#include "tap.h"
#define BUFSIZE 4096
#define HYSTERESIS_LIMIT 3000
-#define SAMPLE_RATE 44100
#define C64_FREQUENCY 985248
-#define TAP_RESOLUTION 8
#define SYNC_PULSE_START 1000
#define SYNC_PULSE_END 15000
#define SYNC_PULSE_LENGTH 378.0
#define SYNC_TEST_TOLERANCE 1.10
-struct tap_header {
- char identifier[12];
- char version;
- char reserved[3];
- unsigned int data_len;
-};
-
// between [x,x+1]
double find_zerocrossing(const std::vector<short> &pcm, int x)
{
double upper = x;
double lower = x + 1;
- while (upper - lower > 1e-6) {
+ while (lower - upper > 1e-3) {
double mid = 0.5f * (upper + lower);
if (lanczos_interpolate(pcm, mid) > 0) {
upper = mid;
int main(int argc, char **argv)
{
+ make_lanczos_weight_table();
std::vector<short> 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);
- }
- }
+ int sample_rate;
+ if (!read_audio_file(argv[1], &pcm, &sample_rate)) {
+ exit(1);
+ }
#if 0
for (int i = 0; i < LEN; ++i) {
if (!true_pulse) {
#if 0
fprintf(stderr, "Ignored down-flank at %.6f seconds due to hysteresis (%d < %d).\n",
- double(i) / SAMPLE_RATE, -min_level_after, HYSTERESIS_LIMIT);
+ double(i) / sample_rate, -min_level_after, HYSTERESIS_LIMIT);
#endif
i = j;
continue;
}
// down-flank!
- double t = find_zerocrossing(pcm, i - 1) * (1.0 / SAMPLE_RATE);
+ double t = find_zerocrossing(pcm, i - 1) * (1.0 / sample_rate);
if (last_downflank > 0) {
pulse p;
p.time = t;
fwrite(&hdr, sizeof(hdr), 1, stdout);
fwrite(tap_data.data(), tap_data.size(), 1, stdout);
+
+ // Output a debug raw file with pulse detection points.
+ fp = fopen("debug.raw", "wb");
+ short one = 32767;
+ short zero = 0;
+ unsigned pulsenum = 0;
+ for (unsigned i = 0; i < pcm.size(); ++i) {
+ unsigned next_pulse = (pulsenum >= pulses.size()) ? INT_MAX : int(pulses[pulsenum].time * sample_rate);
+ if (i >= next_pulse) {
+ fwrite(&one, sizeof(one), 1, fp);
+ ++pulsenum;
+ } else {
+ fwrite(&zero, sizeof(zero), 1, fp);
+ }
+ }
+ fclose(fp);
}