logo

bytemedia

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

tap_code.c (2127B)


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