baud

Modem simulator
git clone https://git.woozle.org/neale/baud.git

commit
1278fa3
parent
1970448
author
Neale Pickett
date
2023-09-25 12:40:37 -0600 MDT
Add code and readme
3 files changed,  +141, -2
A baud.c
R LICENSE => COPYING.txt
+0, -0
M README.md
+61, -2
 1@@ -1,3 +1,62 @@
 2-# baud
 3+---
 4+title: baud.c
 5+---
 6 
 7-Modem simulator
 8+[baud.c](baud.c) is a program to simulate going through a modem.
 9+It reads stdin, and prints it to stdout at the provided baud rate (bits per second).
10+
11+
12+Building
13+--------
14+
15+Download [baud.c](baud.c). Change to that directory, and type
16+
17+    make baud
18+
19+That will generate a file named `baud` in whatever directory you're in.
20+If you like,
21+you can put it in `~/bin` or `~/.local/bin` or `/usr/games/bin` or
22+wherever you prefer.
23+
24+
25+Running
26+-------
27+
28+If you'd like to see what life was like when I got my first modem, try
29+
30+    cat file | ./baud 110 40
31+
32+Run that for a few hours, then try
33+
34+    cat file | ./baud 1200 20
35+
36+And you will understand how mind-blowingly fast 1200 baud modems were at the time.
37+
38+    frotz zork1.zip | ./baud 4800
39+
40+Gives Zork a retro vibe,
41+without being so slow that it's aggravating.
42+I don't think more than a dozen or so people every played Zork over a modem link,
43+but whatever.
44+
45+
46+Why
47+---
48+
49+Every 10 years or so, somebody asks me for this program.
50+I don't know why.
51+
52+The other day it happened again, and I couldn't find it soon enough,
53+so I just wrote it again from scratch.
54+I'm putting it on my web site so I don't have to write it again.
55+
56+
57+License
58+-------
59+
60+I'm placing this in the public domain.
61+So there's no license.
62+
63+Some jurisdictions don't recognize the existence of a public domain.
64+If you live in one of those,
65+you can use the terms of [Creative Commons 0](COPYING.txt).
A baud.c
+80, -0
 1@@ -0,0 +1,80 @@
 2+/*
 3+ * Pretend to be a modem by throttling output.
 4+ *
 5+ * 2023-09-12 
 6+ * Neale Pickett <neale@woozle.org>
 7+ *
 8+ * To the extent possible under law, 
 9+ * I waive all copyright and related or neighboring rights to this software.
10+ */
11+
12+#include <stdio.h>
13+#include <stdlib.h>
14+#include <stddef.h>
15+#include <sysexits.h>
16+#include <unistd.h>
17+
18+const int MICROSECOND = 1;
19+const int MILLISECOND = 1000 * MICROSECOND;
20+const int SECOND = 1000 * MILLISECOND;
21+
22+const int NOISINESS_DENOMINATOR = 36000;
23+const int NOISELEN_DEFAULT = 16;
24+
25+int
26+usage(char *me, char *error) {
27+    if (error) {
28+        fprintf(stderr, "ERROR: %s\n", error);
29+    }
30+    fprintf(stderr, "Usage: %s BAUD [NOISINESS] [NOISELEN]\n", me);
31+    fprintf(stderr, "\n");
32+    fprintf(stderr, "Reads stdin, and writes it back to stdout at BAUD bits per second.\n");
33+    fprintf(stderr, "\n");
34+    fprintf(stderr, "NOISINESS\tEvery bit can begin line noise, with probability NOISINESS/%d\n", NOISINESS_DENOMINATOR);
35+    fprintf(stderr, "NOISELEN\tUp to this many bits of noise happens per burst (default: %d)\n", NOISELEN_DEFAULT);
36+    return EX_USAGE;
37+}
38+
39+int
40+main(int argc, char *argv[]) {
41+    if (argc < 2) {
42+        return usage(argv[0], NULL);
43+    }
44+
45+    int baud = atoi(argv[1]);
46+    if (baud < 1) {
47+        return usage(argv[0], "Invalid baud rate");
48+    }
49+
50+    int noisiness = 0;
51+    if (argc > 2) {
52+        noisiness = atoi(argv[2]);
53+    }
54+    int noiselen = NOISELEN_DEFAULT;
55+    if (argc > 3) {
56+        noiselen = atoi(argv[3]);
57+    }
58+
59+    int cps = baud / 10; // 8N1 has 10 bits per octet: 8 data, 1 start, 1 parity
60+    int delay = SECOND / cps;
61+    int noisybits = 0;
62+    int c;
63+    while ((c = getchar()) != EOF) {
64+        usleep(delay);
65+        for (int bit = 0; bit < 8; bit++) {
66+            int r = rand() % NOISINESS_DENOMINATOR;
67+            if (r < noisiness) {
68+                noisybits = rand() % noiselen;
69+            }
70+
71+            if (noisybits) {
72+                c ^= (rand() & 1) << bit;
73+                noisybits -= 1;
74+            }
75+        }
76+        putchar(c);
77+        fflush(stdout);
78+    }
79+    
80+    return EX_OK;
81+}