tap_code.c (2127B)
- // echo 'hello world' | ./tap_code | $PLAYER -
- // $PLAYER: Any au(5) aware audio player (sox's play(1), mpv, …)
- // https://en.wikipedia.org/wiki/Tap_code
- #define _POSIX_C_SOURCE 200809L
- #include "au.h"
- #include <inttypes.h> // uint32_t
- #include <stdio.h> // getchar(), putchar(), fputs()
- // Fuckings to GNU; Love to musl libc
- // https://drewdevault.com/2020/09/25/A-story-of-two-libcs.html
- int
- isalpha(int c)
- {
- return ((unsigned)c | 32) - 'a' < 26;
- }
- int
- toupper(int c)
- {
- // 'A' - 'a' = -32
- return c - 32;
- }
- int dur = 8000 / 25; // time unit length
- int t = 0;
- // 'Z' = 0d90
- static int tap_code[26][2] = {
- {1, 1}, // A
- {1, 2}, // B
- {1, 3}, // C
- {1, 4}, // D
- {1, 5}, // E
- {2, 1}, // F
- {2, 2}, // G
- {2, 3}, // H
- {2, 4}, // I
- {2, 5}, // J
- {1, 3}, // K = C
- {3, 1}, // L
- {3, 2}, // M
- {3, 3}, // N
- {3, 4}, // O
- {3, 5}, // P
- {4, 1}, // Q
- {4, 2}, // R
- {4, 3}, // S
- {4, 4}, // T
- {4, 5}, // U
- {5, 1}, // V
- {5, 2}, // W
- {5, 3}, // X
- {5, 4}, // Y
- {5, 5}, // Z
- };
- void
- tap(int tone, int dur_multiplier)
- {
- for(int i = 0; i < dur * dur_multiplier; i++, t++)
- {
- putchar((t++ * tone % 30) * 0.80);
- }
- }
- void
- code_to_tap(int code)
- {
- for(int d = 0; d < code; d++)
- {
- tap(1, 1);
- tap(0, 2);
- }
- }
- int
- main(void)
- {
- // Use AU defaults
- struct au_header header = {.offset = 24, // no-annotation, in octets
- .length = 0xFFFFFFFF, // unknown data size
- .encoding = AU_ENCODING_8B_LPCM,
- .samplerate = 8000, // Hz
- .channels = 1};
- // fd 1 is stdout
- write_au_header(1, &header);
- fputs("ASCII text in, raw audio out", stderr);
- int c = 0;
- while((c = getchar()) != -1)
- {
- if(isalpha(c))
- {
- if(c >= 'a' && c <= 'z')
- {
- c = c - 'a';
- }
- else if(c >= 'A' && c <= 'Z')
- {
- c = c - 'A';
- }
- code_to_tap(tap_code[c][0]);
- tap(0, 3);
- code_to_tap(tap_code[c][1]);
- }
- else if(c == ' ')
- {
- tap(0, 7);
- }
- else
- {
- tap(2, 1);
- }
- tap(0, 8);
- }
- return 0;
- }