au.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. #include <assert.h>
  2. #include <ctype.h>
  3. #include <errno.h>
  4. #include <stddef.h>
  5. #include <stdint.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include "au.h"
  10. #include "common.h"
  11. struct strmap {
  12. const char *str;
  13. uint32_t val;
  14. };
  15. static const struct strmap strmap[] = {
  16. { "ULAW", AU_ULAW },
  17. { "MULAW", AU_ULAW },
  18. { "U-LAW", AU_ULAW },
  19. { "MU-LAW", AU_ULAW },
  20. { "PCM8", AU_PCM8 },
  21. { "PCM-8", AU_PCM8 },
  22. { "PCM16", AU_PCM16 },
  23. { "PCM-16", AU_PCM16 },
  24. { "PCM24", AU_PCM24 },
  25. { "PCM-24", AU_PCM24 },
  26. { "PCM32", AU_PCM32 },
  27. { "PCM-32", AU_PCM32 },
  28. { "FLOAT", AU_FLOAT32 },
  29. { "FLOAT32", AU_FLOAT32 },
  30. { "FLOAT-32", AU_FLOAT32 },
  31. { "DOUBLE", AU_FLOAT64 },
  32. { "FLOAT64", AU_FLOAT64 },
  33. { "FLOAT-64", AU_FLOAT64 },
  34. { "FIXED8", AU_FIXED8 },
  35. { "FIXED-8", AU_FIXED8 },
  36. { "FIXED16", AU_FIXED16 },
  37. { "FIXED-16", AU_FIXED16 },
  38. { "FIXED24", AU_FIXED24 },
  39. { "FIXED-24", AU_FIXED24 },
  40. { "FIXED32", AU_FIXED32 },
  41. { "FIXED-32", AU_FIXED32 },
  42. { "ALAW", AU_ALAW },
  43. { "A-LAW", AU_ALAW },
  44. { NULL, 0 }
  45. };
  46. static const uint8_t au_magic[4] = { 0x2E, 0x73, 0x6E, 0x64 };
  47. int
  48. au_gethdr(struct au *au, const void *b)
  49. {
  50. const uint8_t *p = b;
  51. assert(au != NULL && b != NULL);
  52. if (memcmp(p, au_magic, sizeof(au_magic)) != 0)
  53. return (-1);
  54. au->au_off = get4(p += 4);
  55. au->au_size = get4(p += 4);
  56. au->au_enc = get4(p += 4);
  57. au->au_rate = get4(p += 4);
  58. au->au_chan = get4(p += 4);
  59. return (0);
  60. }
  61. int
  62. au_puthdr(struct au *au, void *b)
  63. {
  64. uint8_t *p = b;
  65. assert(au != NULL && b != NULL);
  66. (void)memcpy(p, au_magic, sizeof(au_magic));
  67. put4((p += 4), au->au_off);
  68. put4((p += 4), au->au_size);
  69. put4((p += 4), au->au_enc);
  70. put4((p += 4), au->au_rate);
  71. put4((p += 4), au->au_chan);
  72. return (0);
  73. }
  74. const char *
  75. au_encstr(uint32_t val)
  76. {
  77. size_t i;
  78. for (i = 0; strmap[i].str != NULL; i++)
  79. if (strmap[i].val == val)
  80. return (strmap[i].str);
  81. return (NULL);
  82. }
  83. size_t
  84. au_encsize(uint32_t enc)
  85. {
  86. switch (enc) {
  87. case AU_ULAW:
  88. return (1);
  89. case AU_PCM8:
  90. return (1);
  91. case AU_PCM16:
  92. return (2);
  93. case AU_PCM24:
  94. return (3);
  95. case AU_PCM32:
  96. return (4);
  97. case AU_FLOAT32:
  98. return (4);
  99. case AU_FLOAT64:
  100. return (8);
  101. case AU_FIXED8:
  102. return (1);
  103. case AU_FIXED16:
  104. return (2);
  105. case AU_FIXED24:
  106. return (3);
  107. case AU_FIXED32:
  108. return (4);
  109. case AU_ALAW:
  110. return (1);
  111. }
  112. return (0);
  113. }
  114. uint32_t
  115. au_strencp(const char *str, const char **ep)
  116. {
  117. char *p;
  118. size_t i;
  119. size_t j;
  120. uint32_t r;
  121. assert(str != NULL);
  122. for (i = 0; strmap[i].str != NULL; i++) {
  123. for (j = 0; str[j] != '\0' && strmap[i].str[j] != '\0'
  124. && toupper(str[j]) == toupper(strmap[i].str[j]);
  125. j++)
  126. /* do nothing */;
  127. if (strmap[i].str[j] == '\0') {
  128. if (ep == NULL && str[j] != '\0')
  129. ERR(EINVAL, 0);
  130. if (ep != NULL)
  131. *ep = str + j;
  132. return (strmap[i].val);
  133. }
  134. }
  135. r = strtoul(str, &p, 0);
  136. if ((r > AU_ENCMAX && p == str) || (ep == NULL && *p != '\0'))
  137. return (0);
  138. if (ep != NULL)
  139. *ep = p;
  140. return (r);
  141. }
  142. int
  143. au_encbswap(uint32_t enc, void *b, size_t size)
  144. {
  145. size_t i;
  146. size_t j;
  147. size_t o;
  148. char *cb = b;
  149. char t;
  150. assert(b != NULL);
  151. if ((o = au_encsize(enc)) < 2)
  152. return (0);
  153. for (i = 0; i < size / o; i++)
  154. for (j = 0; j < o / 2; j++) {
  155. t = cb[i * o + j];
  156. cb[i * o + j] = cb[i * o + (o - j - 1)];
  157. cb[i * o + (o - j - 1)] = t;
  158. }
  159. return (0);
  160. }
  161. int
  162. au_encnswap(uint32_t enc, void *b, size_t size)
  163. {
  164. const uint32_t e = 1;
  165. return (((const char *)&e)[0] ? au_encbswap(enc, b, size) : 0);
  166. }