morse.c (3171B)
- // echo 'hello world' | ./morse | $PLAYER -
- // $PLAYER: Any au(5) aware audio player (sox's play(1), mpv, …)
- #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
- isdigit(int c)
- {
- return (unsigned)c - '0' < 10;
- }
- int
- isalnum(int c)
- {
- return isalpha(c) || isdigit(c);
- }
- int
- toupper(int c)
- {
- // 'A' - 'a' = -32
- return c - 32;
- }
- /*
- * Morse:
- *
- * dot: 1 unit
- * dash: 3 units
- * dot/dash gap: 1 unit
- * letter gap: 3 units
- * word gap: 7 units
- */
- // 'Z' = 0d90
- static char *morse_itu[91];
- int
- morse_init()
- {
- morse_itu['A'] = ". ---";
- morse_itu['B'] = "--- . . .";
- morse_itu['C'] = "--- . --- .";
- morse_itu['D'] = "--- . .";
- morse_itu['E'] = ".";
- morse_itu['F'] = ". . --- .";
- morse_itu['G'] = "--- --- .";
- morse_itu['H'] = ". . . .";
- morse_itu['I'] = ". .";
- morse_itu['J'] = ". --- --- ---";
- morse_itu['K'] = "--- . ---";
- morse_itu['L'] = ". --- . .";
- morse_itu['M'] = "--- ---";
- morse_itu['N'] = "--- .";
- morse_itu['O'] = "--- --- ---";
- morse_itu['P'] = ". --- --- .";
- morse_itu['Q'] = "--- --- . ---";
- morse_itu['R'] = ". --- .";
- morse_itu['S'] = ". . .";
- morse_itu['T'] = "---";
- morse_itu['U'] = ". . ---";
- morse_itu['V'] = ". . . ---";
- morse_itu['W'] = ". --- ---";
- morse_itu['X'] = "--- . . ---";
- morse_itu['Y'] = "--- . --- ---";
- morse_itu['Z'] = "--- --- . .";
- morse_itu['1'] = ". --- --- --- ---";
- morse_itu['2'] = ". . --- --- ---";
- morse_itu['3'] = ". . . --- ---";
- morse_itu['4'] = ". . . . ---";
- morse_itu['5'] = ". . . . .";
- morse_itu['6'] = "--- . . . .";
- morse_itu['7'] = "--- --- . . .";
- morse_itu['8'] = "--- --- --- . .";
- morse_itu['9'] = "--- --- --- --- .";
- morse_itu['0'] = "--- --- --- --- ---";
- return 1;
- }
- int
- main(void)
- {
- morse_init();
- // 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};
- int t = 0;
- int tone = 0;
- int dur = 8000 / 10; // time unit length
- // 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(isalnum(c))
- {
- if(c >= 'a' && c <= 'z')
- {
- c = toupper(c);
- }
- char *code = morse_itu[c];
- while(code[0] != '\0')
- {
- if(code[0] == '.' || code[0] == '-')
- {
- tone = 1;
- }
- else
- {
- tone = 0;
- }
- for(int i = 0; i < dur; i++, t++)
- {
- putchar(t++ * tone % 30);
- }
- code++;
- }
- // letter separation; 3 units
- for(int i = 0; i < dur * 3; i++, t++)
- {
- putchar(t++ * 0 % 30);
- }
- }
- else
- {
- // word separation; 7 units
- for(int i = 0; i < dur * 7; i++, t++)
- {
- putchar(t++ * 0 % 30);
- }
- }
- }
- return 0;
- }