diff --git a/content/misc/baud.c b/content/misc/baud.c new file mode 100644 index 0000000..e90e31b --- /dev/null +++ b/content/misc/baud.c @@ -0,0 +1,84 @@ +/* + * Pretend to be a modem by throttling output. + * + * 2023-09-12 + * Neale Pickett + * + * To the extent possible under law, + * I waive all copyright and related or neighboring rights to this software. + */ + +#include +#include +#include +#include +#include + +const int MICROSECOND = 1; +const int MILLISECOND = 1000 * MICROSECOND; +const int SECOND = 1000 * MILLISECOND; + +const int NOISINESS_DENOMINATOR = 36000; +const int NOISELEN_DEFAULT = 16; + +int +usage(char *me, char *error) { + if (error) { + fprintf(stderr, "ERROR: %s\n", error); + } + fprintf(stderr, "Usage: %s BAUD [NOISINESS] [NOISELEN]\n", me); + fprintf(stderr, "\n"); + fprintf(stderr, "Reads stdin, and writes it back to stdout at BAUD bits per second.\n"); + fprintf(stderr, "\n"); + fprintf(stderr, "NOISINESS\tEvery bit can begin line noise, with probability NOISINESS/%d\n", NOISINESS_DENOMINATOR); + fprintf(stderr, "NOISELEN\tUp to this many bits of noise happens per burst (default: %d)\n", NOISELEN_DEFAULT); + return EX_USAGE; +} + +int +main(int argc, char *argv[]) { + if (argc < 2) { + return usage(argv[0], NULL); + } + + int baud = atoi(argv[1]); + if (baud < 1) { + return usage(argv[0], "Invalid baud rate"); + } + + int noisiness = 0; + if (argc > 2) { + noisiness = atoi(argv[2]); + } + int noiselen = NOISELEN_DEFAULT; + if (argc > 3) { + noiselen = atoi(argv[3]); + } + + int cps = baud / 8; + int delay = SECOND / cps; + int noisybits = 0; + int c; + while ((c = getchar()) != EOF) { + usleep(delay); + for (int bit = 0; bit < 8; bit++) { + int r = rand() % NOISINESS_DENOMINATOR; + if (r < noisiness) { + noisybits = rand() % noiselen; + } + + if (noisybits) { + if (rand() < RAND_MAX/2) { + c &= ~(1<