logo

bytemedia

Home to byte-level sounds, images, videos, … git clone https://hacktivis.me/git/bytemedia.git

morse.c (3171B)


  1. // echo 'hello world' | ./morse | $PLAYER -
  2. // $PLAYER: Any au(5) aware audio player (sox's play(1), mpv, …)
  3. #define _POSIX_C_SOURCE 200809L
  4. #include "au.h"
  5. #include <inttypes.h> // uint32_t
  6. #include <stdio.h> // getchar(), putchar(), fputs()
  7. // Fuckings to GNU; Love to musl libc
  8. // https://drewdevault.com/2020/09/25/A-story-of-two-libcs.html
  9. int
  10. isalpha(int c)
  11. {
  12. return ((unsigned)c | 32) - 'a' < 26;
  13. }
  14. int
  15. isdigit(int c)
  16. {
  17. return (unsigned)c - '0' < 10;
  18. }
  19. int
  20. isalnum(int c)
  21. {
  22. return isalpha(c) || isdigit(c);
  23. }
  24. int
  25. toupper(int c)
  26. {
  27. // 'A' - 'a' = -32
  28. return c - 32;
  29. }
  30. /*
  31. * Morse:
  32. *
  33. * dot: 1 unit
  34. * dash: 3 units
  35. * dot/dash gap: 1 unit
  36. * letter gap: 3 units
  37. * word gap: 7 units
  38. */
  39. // 'Z' = 0d90
  40. static char *morse_itu[91];
  41. int
  42. morse_init()
  43. {
  44. morse_itu['A'] = ". ---";
  45. morse_itu['B'] = "--- . . .";
  46. morse_itu['C'] = "--- . --- .";
  47. morse_itu['D'] = "--- . .";
  48. morse_itu['E'] = ".";
  49. morse_itu['F'] = ". . --- .";
  50. morse_itu['G'] = "--- --- .";
  51. morse_itu['H'] = ". . . .";
  52. morse_itu['I'] = ". .";
  53. morse_itu['J'] = ". --- --- ---";
  54. morse_itu['K'] = "--- . ---";
  55. morse_itu['L'] = ". --- . .";
  56. morse_itu['M'] = "--- ---";
  57. morse_itu['N'] = "--- .";
  58. morse_itu['O'] = "--- --- ---";
  59. morse_itu['P'] = ". --- --- .";
  60. morse_itu['Q'] = "--- --- . ---";
  61. morse_itu['R'] = ". --- .";
  62. morse_itu['S'] = ". . .";
  63. morse_itu['T'] = "---";
  64. morse_itu['U'] = ". . ---";
  65. morse_itu['V'] = ". . . ---";
  66. morse_itu['W'] = ". --- ---";
  67. morse_itu['X'] = "--- . . ---";
  68. morse_itu['Y'] = "--- . --- ---";
  69. morse_itu['Z'] = "--- --- . .";
  70. morse_itu['1'] = ". --- --- --- ---";
  71. morse_itu['2'] = ". . --- --- ---";
  72. morse_itu['3'] = ". . . --- ---";
  73. morse_itu['4'] = ". . . . ---";
  74. morse_itu['5'] = ". . . . .";
  75. morse_itu['6'] = "--- . . . .";
  76. morse_itu['7'] = "--- --- . . .";
  77. morse_itu['8'] = "--- --- --- . .";
  78. morse_itu['9'] = "--- --- --- --- .";
  79. morse_itu['0'] = "--- --- --- --- ---";
  80. return 1;
  81. }
  82. int
  83. main(void)
  84. {
  85. morse_init();
  86. // Use AU defaults
  87. struct au_header header = {.offset = 24, // no-annotation, in octets
  88. .length = 0xFFFFFFFF, // unknown data size
  89. .encoding = AU_ENCODING_8B_LPCM,
  90. .samplerate = 8000, // Hz
  91. .channels = 1};
  92. int t = 0;
  93. int tone = 0;
  94. int dur = 8000 / 10; // time unit length
  95. // fd 1 is stdout
  96. write_au_header(1, &header);
  97. fputs("ASCII text in, raw audio out", stderr);
  98. int c = 0;
  99. while((c = getchar()) != -1)
  100. {
  101. if(isalnum(c))
  102. {
  103. if(c >= 'a' && c <= 'z')
  104. {
  105. c = toupper(c);
  106. }
  107. char *code = morse_itu[c];
  108. while(code[0] != '\0')
  109. {
  110. if(code[0] == '.' || code[0] == '-')
  111. {
  112. tone = 1;
  113. }
  114. else
  115. {
  116. tone = 0;
  117. }
  118. for(int i = 0; i < dur; i++, t++)
  119. {
  120. putchar(t++ * tone % 30);
  121. }
  122. code++;
  123. }
  124. // letter separation; 3 units
  125. for(int i = 0; i < dur * 3; i++, t++)
  126. {
  127. putchar(t++ * 0 % 30);
  128. }
  129. }
  130. else
  131. {
  132. // word separation; 7 units
  133. for(int i = 0; i < dur * 7; i++, t++)
  134. {
  135. putchar(t++ * 0 % 30);
  136. }
  137. }
  138. }
  139. return 0;
  140. }