mpg.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. #include <assert.h>
  2. #include <errno.h>
  3. #include <limits.h>
  4. #include <stdarg.h>
  5. #include <stddef.h>
  6. #include <stdint.h>
  7. #include <stdlib.h>
  8. #include <time.h>
  9. #include <fcntl.h>
  10. #include <unistd.h>
  11. #include <mpg123.h>
  12. #include "../au.h"
  13. #include "../common.h"
  14. #include "afile.h"
  15. struct afile {
  16. mpg123_handle *h;
  17. uint32_t enc;
  18. long rate;
  19. int channels;
  20. int first;
  21. int fd;
  22. };
  23. enum {
  24. A_NULL,
  25. A_ENC,
  26. A_RATE,
  27. A_CHAN
  28. };
  29. const struct a_lookup stab[] = {
  30. { "enc", A_ENC },
  31. { "encoding", A_ENC },
  32. { "rate", A_RATE },
  33. { "chan", A_CHAN },
  34. { "channel", A_CHAN },
  35. { "channels", A_CHAN },
  36. { NULL, A_NULL }
  37. };
  38. static uint32_t mpg123_au_enc(int);
  39. static int au_mpg123_enc(uint32_t);
  40. struct afile *
  41. af_open(const char *file)
  42. {
  43. int fd;
  44. if (file == NULL)
  45. ERR(EINVAL, NULL);
  46. if ((fd = open(file, O_RDONLY)) < 0)
  47. return (NULL);
  48. return (af_fdopen(fd));
  49. }
  50. struct afile *
  51. af_fdopen(int fd)
  52. {
  53. struct afile *a;
  54. long rate;
  55. int chan;
  56. int enc;
  57. if ((a = malloc(sizeof(struct afile))) == NULL)
  58. goto err;
  59. a->fd = fd;
  60. a->h = NULL;
  61. if (mpg123_init() != MPG123_OK)
  62. return NULL;
  63. if ((a->h = mpg123_new(NULL, NULL)) == NULL ||
  64. mpg123_param(a->h, MPG123_ADD_FLAGS, MPG123_QUIET, 0)
  65. != MPG123_OK || mpg123_open_fd(a->h, a->fd) != MPG123_OK)
  66. goto err;
  67. if (mpg123_getformat(a->h, &rate, &chan, &enc)
  68. != MPG123_OK || rate > (int)(~0U >> 1)) {
  69. mpg123_close(a->h);
  70. goto err;
  71. }
  72. switch (chan) {
  73. case MPG123_MONO:
  74. a->channels = 1;
  75. break;
  76. case MPG123_STEREO:
  77. a->channels = 2;
  78. break;
  79. }
  80. a->rate = rate;
  81. a->enc = mpg123_au_enc(enc);
  82. return (a);
  83. err:
  84. if (a != NULL) {
  85. if (a->h != NULL)
  86. mpg123_delete(a->h);
  87. if (a->fd >= 0)
  88. close(a->fd);
  89. free(a);
  90. }
  91. mpg123_exit();
  92. return (NULL);
  93. }
  94. void
  95. af_close(struct afile *a)
  96. {
  97. if (a == NULL)
  98. return;
  99. if (a->fd >= 0)
  100. close(a->fd);
  101. if (a->h != NULL) {
  102. mpg123_close(a->h);
  103. mpg123_delete(a->h);
  104. }
  105. mpg123_exit();
  106. free(a);
  107. }
  108. int
  109. af_get(struct afile *a, const char *s, ...)
  110. {
  111. va_list ap;
  112. ssize_t r;
  113. size_t l;
  114. int n;
  115. int v;
  116. if (a == NULL || s == NULL)
  117. ERR(EINVAL, -1);
  118. va_start(ap, s);
  119. for (n = 0; (r = a_lookup(stab, s, &v)) > 0; n++, s += r)
  120. switch (v) {
  121. case A_ENC:
  122. *va_arg(ap, uint32_t *) = a->enc;
  123. break;
  124. case A_RATE:
  125. *va_arg(ap, uint32_t *) = a->rate;
  126. break;
  127. case A_CHAN:
  128. *va_arg(ap, uint32_t *) = a->channels;
  129. break;
  130. default:
  131. goto err;
  132. }
  133. if (r == 0) {
  134. va_end(ap);
  135. return (n);
  136. }
  137. err:
  138. va_end(ap);
  139. ERR(EINVAL, n);
  140. }
  141. int
  142. af_set(struct afile *a, const char *s, ...)
  143. {
  144. va_list ap;
  145. ssize_t r;
  146. uint32_t t;
  147. int n;
  148. int v;
  149. if (a == NULL || s == NULL)
  150. ERR(EINVAL, -1);
  151. va_start(ap, s);
  152. for (n = 0; (r = a_lookup(stab, s, &v)) > 0; n++, s += r)
  153. switch (v) {
  154. case A_ENC:
  155. a->enc = va_arg(ap, uint32_t);
  156. break;
  157. case A_RATE:
  158. if ((t = va_arg(ap, uint32_t)) > LONG_MAX)
  159. goto err;
  160. a->rate = t;
  161. break;
  162. case A_CHAN:
  163. if ((t = va_arg(ap, uint32_t)) == 0 || t > 0)
  164. goto err;
  165. a->channels = t;
  166. break;
  167. default:
  168. goto err;
  169. }
  170. if (r == 0) {
  171. va_end(ap);
  172. return (n);
  173. }
  174. err:
  175. va_end(ap);
  176. ERR(EINVAL, n);
  177. }
  178. ssize_t
  179. af_read(struct afile *a, void *b, size_t s)
  180. {
  181. size_t r;
  182. if (a == NULL || b == NULL)
  183. ERR(EINVAL, -1);
  184. if (a->first) {
  185. if (mpg123_format(a->h, a->rate, a->channels,
  186. au_mpg123_enc(a->enc)) != MPG123_OK)
  187. return (-1);
  188. a->first = 0;
  189. }
  190. if (s == 0)
  191. return (0);
  192. if (mpg123_read(a->h, b, s, &r) != MPG123_OK)
  193. ERR(EIO, -1);
  194. if (au_encnswap(a->enc, b, r) != 0)
  195. return (-1);
  196. return (r);
  197. }
  198. struct timespec
  199. af_seek(struct afile *a, struct timespec ts, int whence)
  200. {
  201. off_t o;
  202. o = ts.tv_sec * a->rate + ts.tv_nsec * a->rate / 1000000000;
  203. o = mpg123_seek(a->h, o, whence);
  204. ts.tv_sec = o / a->rate;
  205. ts.tv_nsec = o % a->rate * 1000000000 / a->rate;
  206. return (ts);
  207. }
  208. struct timespec
  209. af_length(struct afile *a)
  210. {
  211. struct timespec ts;
  212. off_t o;
  213. o = mpg123_length(a->h);
  214. ts.tv_sec = o / a->rate;
  215. ts.tv_nsec = o % a->rate * 1000000000 / a->rate;
  216. return (ts);
  217. }
  218. uint32_t
  219. mpg123_au_enc(int enc)
  220. {
  221. switch (enc) {
  222. case MPG123_ENC_ULAW_8:
  223. return (AU_ULAW);
  224. case MPG123_ENC_UNSIGNED_8:
  225. /* FALLTHROUGH */
  226. case MPG123_ENC_SIGNED_8:
  227. return (AU_PCM8);
  228. case MPG123_ENC_UNSIGNED_16:
  229. /* FALLTHROUGH */
  230. case MPG123_ENC_SIGNED_16:
  231. return (AU_PCM16);
  232. case MPG123_ENC_UNSIGNED_24:
  233. /* FALLTHROUGH */
  234. case MPG123_ENC_SIGNED_24:
  235. return (AU_PCM24);
  236. case MPG123_ENC_UNSIGNED_32:
  237. /* FALLTHROUGH */
  238. case MPG123_ENC_SIGNED_32:
  239. return (AU_PCM32);
  240. case MPG123_ENC_FLOAT_32:
  241. return (AU_FLOAT32);
  242. case MPG123_ENC_FLOAT_64:
  243. return (AU_FLOAT64);
  244. case MPG123_ENC_ALAW_8:
  245. return (AU_ULAW);
  246. }
  247. return (0);
  248. }
  249. int
  250. au_mpg123_enc(uint32_t enc)
  251. {
  252. switch (enc) {
  253. case AU_ULAW:
  254. return (MPG123_ENC_ULAW_8);
  255. case AU_PCM8:
  256. return (MPG123_ENC_SIGNED_8);
  257. case AU_PCM16:
  258. return (MPG123_ENC_SIGNED_16);
  259. case AU_PCM24:
  260. return (MPG123_ENC_SIGNED_24);
  261. case AU_PCM32:
  262. return (MPG123_ENC_SIGNED_32);
  263. case AU_FLOAT32:
  264. return (MPG123_ENC_FLOAT_32);
  265. case AU_FLOAT64:
  266. return (MPG123_ENC_FLOAT_64);
  267. case AU_ALAW:
  268. return (MPG123_ENC_ALAW_8);
  269. }
  270. return (0);
  271. }