/* * SAME/EAS decoder, 2006 Ben Winslow * with credit to Zinx Verituse */ /* FIXME: * - The power thresholds are completely arbitrary. They should probably be * based on some average of the sample window. * - No window synchronization. This means there's some luck involved in * a successful decoding, especially with a noisy signal. * - Doing proper FFT might yield better results? * - There should be an option to require a valid preamble before deciding * that we're synchronized. */ #include #include #include #define ABS(x) ((x) < 0 ? ((x) * -1) : (x)) #define SRATE 44100.0 #define BAND 260.0 #define NSAMP (int)((1920.0/1000000.0) * SRATE) #define MARK_FREQ 2083.3 #define SPACE_FREQ 1562.5 int main(int argc, char *argv[]) { short sample, window[NSAMP]; int windpos = 0, havesync = 0, x; double mark_sine, mark_cosine; double space_sine, space_cosine; double mark_power, space_power; int accum = 0, accumbits = 0; printf("Window: %d samples\n", NSAMP); while (read(0, &sample, sizeof(sample)) == sizeof(sample)) { // printf("Sample: %d\n", sample); window[windpos] = sample; windpos++; if (windpos >= NSAMP) { mark_sine = mark_cosine = space_sine = space_cosine = 0.0; for (x = 0; x < NSAMP; x++) { mark_sine += window[x] * sin(MARK_FREQ * M_PI * 2 * (double)x / SRATE); space_sine += window[x] * sin(SPACE_FREQ * M_PI * 2 * (double)x / SRATE); mark_cosine += window[x] * cos(MARK_FREQ * M_PI * 2 * (double)x / SRATE); space_cosine += window[x] * cos(SPACE_FREQ * M_PI * 2 * (double)x / SRATE); } mark_power = sqrt(pow(mark_sine, 2) + pow(mark_cosine, 2)); space_power = sqrt(pow(space_sine, 2) + pow(space_cosine, 2)); if (mark_power > 10000.0 || space_power > 10000.0) { // printf("power[%.1fHz] = %f - power[%.1fHz] = %f :: %s\n", MARK_FREQ, mark_power, SPACE_FREQ, space_power, mark_power > space_power ? "MARK" : "SPACE"); accum >>= 1; if (mark_power > space_power) accum |= 0x80; accumbits++; // printf("[s%d] accum[%02x]\n", havesync, accum); if (!havesync) { if ((accum & 0xff) == 0xab) { havesync = 1; accum = accumbits = 0; printf("[got sync]"); } } else if (accumbits == 8) { if ((accum & 0xff) < 0x20 || (accum & 0xff) >= 0x80) printf("[%02x]", accum & 0xff); else printf("%c", accum & 0xff); accum = accumbits = 0; } } else if (havesync) { printf("[lost sync]\n"); havesync = 0; } fflush(stdout); windpos = 0; } } printf("[eof!]\n"); return 0; }