auconv.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681
  1. #include <assert.h>
  2. #include <ctype.h>
  3. #include <errno.h>
  4. #include <inttypes.h>
  5. #include <limits.h>
  6. #include <signal.h>
  7. #include <stddef.h>
  8. #include <stdint.h>
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <unistd.h>
  13. #ifdef USE_CAPSICUM
  14. #include <sys/capsicum.h>
  15. #endif
  16. #include <err.h>
  17. #include <sysexits.h>
  18. #include "au.h"
  19. #include "common.h"
  20. #ifndef BSIZE
  21. #define BSIZE 1024
  22. #endif
  23. enum {
  24. MODE_AU,
  25. MODE_RAW,
  26. MODE_NOHDR
  27. };
  28. #ifdef SIGINFO
  29. static size_t info_in = 0;
  30. static size_t info_out = 0;
  31. #endif
  32. #ifdef SIGINFO
  33. static void siginfo(int);
  34. #endif
  35. static size_t conv(uint32_t, const void *, size_t, uint32_t, void *,
  36. size_t, size_t);
  37. static size_t pcmconv(void *, size_t, void *, uint32_t);
  38. static size_t ulawconv(uint8_t, void *, uint32_t);
  39. static size_t alawconv(uint8_t, void *, uint32_t);
  40. static size_t floatconv(void *, size_t, void *, uint32_t);
  41. static ssize_t ncpy(int, int, void *, size_t);
  42. static unsigned clz_16(uint16_t);
  43. int
  44. main(int argc, char *argv[])
  45. {
  46. char hb[AU_SIZE];
  47. #ifdef USE_CAPSICUM
  48. cap_rights_t rights;
  49. #endif
  50. struct au iau = AU_INITIALIZER;
  51. struct au oau = AU_INITIALIZER;
  52. int (*iswap)(uint32_t, void *, size_t) = NULL;
  53. int (*oswap)(uint32_t, void *, size_t) = NULL;
  54. size_t bsize = BSIZE;
  55. size_t ibsize = 0;
  56. size_t obsize = 0;
  57. void *ib = NULL;
  58. void *ob = NULL;
  59. const char *cp;
  60. char *p;
  61. ssize_t r;
  62. ssize_t t;
  63. ssize_t i;
  64. int imode = MODE_AU;
  65. int omode = MODE_AU;
  66. int c;
  67. #ifdef USE_PLEDGE
  68. pledge("stdio", NULL);
  69. #endif
  70. #ifdef USE_CAPSICUM
  71. if (cap_enter() == -1 && errno != ENOSYS)
  72. err(EX_OSERR, "Could not enter capibility mode");
  73. cap_rights_init(&rights, CAP_READ);
  74. if (cap_rights_limit(STDIN_FILENO, &rights) == -1 &&
  75. errno != ENOSYS)
  76. err(EX_OSERR, "Could not limit the input");
  77. cap_rights_init(&rights, CAP_WRITE);
  78. if (cap_rights_limit(STDOUT_FILENO, &rights) == -1 &&
  79. errno != ENOSYS)
  80. err(EX_OSERR, "Could not limit the output");
  81. if (cap_rights_limit(STDERR_FILENO, &rights) == -1 &&
  82. errno != ENOSYS)
  83. err(EX_OSERR, "Could not limit the standard error");
  84. #endif
  85. while ((c = getopt(argc, argv, "b:c:i:j:o:r:s:")) != -1)
  86. switch (c) {
  87. case 'b':
  88. bsize = strtoul(optarg, &p, 0);
  89. if (p == optarg || *p != '\0')
  90. err(EX_USAGE, "Bad number %s", optarg);
  91. break;
  92. case 'c':
  93. iau.au_chan = strtou32(optarg);
  94. if (imode != MODE_RAW)
  95. imode = MODE_NOHDR;
  96. break;
  97. case 'i':
  98. imode = MODE_AU;
  99. if (strncasecmp(optarg, "r", 1) == 0) {
  100. optarg++;
  101. if (strncasecmp(optarg, "aw", 2) == 0)
  102. optarg += 2;
  103. imode = MODE_RAW;
  104. if (*optarg == '\0')
  105. break;
  106. }
  107. if ((iau.au_enc = au_strencp(optarg, &cp)) == 0)
  108. errx(EX_USAGE, "Bad encoding %s",
  109. optarg);
  110. if (imode != MODE_RAW)
  111. imode = MODE_NOHDR;
  112. if (*cp == '\0')
  113. break;
  114. if (toupper(cp[0]) == 'E' && cp[1] != '\0')
  115. p++;
  116. switch (toupper(*cp)) {
  117. case 'B':
  118. cp++;
  119. iswap = NULL;
  120. imode = MODE_RAW;
  121. break;
  122. case 'L':
  123. cp++;
  124. iswap = &au_encbswap;
  125. imode = MODE_RAW;
  126. break;
  127. case 'N':
  128. cp++;
  129. iswap = &au_encnswap;
  130. imode = MODE_RAW;
  131. break;
  132. default:
  133. err(EX_USAGE, "Bad encoding %s",
  134. optarg);
  135. break;
  136. }
  137. if (toupper(cp[0]) == 'E')
  138. cp++;
  139. if (*cp != '\0')
  140. errx(EX_USAGE, "Bad encoding %s",
  141. optarg);
  142. break;
  143. case 'j':
  144. iau.au_off = strtou32(optarg);
  145. if (imode != MODE_RAW)
  146. imode = MODE_NOHDR;
  147. break;
  148. case 'o':
  149. omode = MODE_AU;
  150. if (strncasecmp(optarg, "r", 1) == 0) {
  151. optarg++;
  152. if (strncasecmp(optarg, "aw", 2) == 0)
  153. optarg += 2;
  154. omode = MODE_RAW;
  155. if (*optarg == '\0')
  156. break;
  157. }
  158. if ((oau.au_enc = au_strencp(optarg, &cp)) == 0)
  159. err(EX_USAGE, "Bad encoding %s",
  160. optarg);
  161. if (*cp == '\0')
  162. break;
  163. if (toupper(cp[0]) == 'E' && cp[1] != '\0')
  164. p++;
  165. switch (toupper(*cp++)) {
  166. case 'B':
  167. oswap = NULL;
  168. imode = MODE_RAW;
  169. break;
  170. case 'L':
  171. oswap = &au_encbswap;
  172. omode = MODE_RAW;
  173. break;
  174. case 'N':
  175. oswap = &au_encnswap;
  176. omode = MODE_RAW;
  177. break;
  178. default:
  179. err(EX_USAGE, "Bad encoding %s",
  180. optarg);
  181. break;
  182. }
  183. if (toupper(cp[0]) == 'E')
  184. cp++;
  185. if (*cp != '\0')
  186. errx(EX_USAGE, "Bad encoding %s",
  187. optarg);
  188. break;
  189. case 'r':
  190. iau.au_rate = strtoul(optarg, &p, 0);
  191. if (p == optarg || *p != '\0')
  192. err(EX_USAGE, "Bad number %s", optarg);
  193. if (imode != MODE_RAW)
  194. imode = MODE_NOHDR;
  195. break;
  196. case 's':
  197. iau.au_size = strtou32(optarg);
  198. if (imode != MODE_RAW)
  199. imode = MODE_NOHDR;
  200. break;
  201. default:
  202. goto usage;
  203. }
  204. #ifdef SIGINFO
  205. (void)signal(SIGINFO, &siginfo);
  206. #endif
  207. while (imode != MODE_AU ||
  208. nread(STDIN_FILENO, hb, sizeof(hb)) == sizeof(hb)) {
  209. if (imode == MODE_AU) {
  210. #ifdef SIGINFO
  211. info_in += AU_SIZE;
  212. #endif
  213. if (au_gethdr(&iau, hb) != 0)
  214. errx(EX_DATAERR, "Bad header");
  215. }
  216. if (au_vsize(&iau) == 0)
  217. err(EX_DATAERR, "Invalid encoding %"PRIu32,
  218. iau.au_enc);
  219. if (ibsize < bsize * au_ssize(&iau)) {
  220. ibsize = bsize * au_ssize(&iau);
  221. if ((ib = ib == NULL ? malloc(ibsize) :
  222. realloc(ib, ibsize)) == NULL)
  223. err(EX_OSERR, "Could not allocate "
  224. "the input array");
  225. }
  226. oau.au_off = iau.au_off;
  227. oau.au_size = iau.au_size == UINT32_MAX ? UINT32_MAX :
  228. iau.au_size / au_vsize(&iau) * au_vsize(&oau);
  229. oau.au_rate = iau.au_rate;
  230. oau.au_chan = iau.au_chan;
  231. if (obsize < bsize * au_ssize(&oau)) {
  232. obsize = bsize * au_ssize(&oau);
  233. if ((ob = ob == NULL ? malloc(obsize) :
  234. realloc(ob, obsize)) == NULL)
  235. err(EX_OSERR, "Could not allocate "
  236. "the output array");
  237. }
  238. if (omode == MODE_AU) {
  239. (void)au_puthdr(&oau, hb);
  240. if (nwrite(STDOUT_FILENO, hb, sizeof(hb)) !=
  241. sizeof(hb))
  242. err(EX_IOERR,
  243. "Could not write audio header");
  244. #ifdef SIGINFO
  245. info_out += AU_SIZE;
  246. #endif
  247. }
  248. if (omode == MODE_RAW) {
  249. for (i = AU_SIZE; i < (size_t)iau.au_off;
  250. i += r) {
  251. if ((r = nread(STDIN_FILENO, ib,
  252. MIN(iau.au_off - i, bsize))) < 0)
  253. err(EX_IOERR,
  254. "error while reading");
  255. #ifdef SIGINFO
  256. info_in += r;
  257. #endif
  258. }
  259. } else {
  260. /* ncpy handles info_in/info_out */
  261. for (i = AU_SIZE; i < (size_t)iau.au_off;
  262. i += r)
  263. if ((r = ncpy(STDIN_FILENO,
  264. STDOUT_FILENO, ib, MIN(
  265. iau.au_off - i, bsize))) < 0)
  266. err(EX_IOERR,
  267. "error while copying "
  268. "stdin -> stdout");
  269. }
  270. while (iau.au_size > 0 && (r = nread(STDIN_FILENO, ib,
  271. MIN(iau.au_size, ibsize))) > 0) {
  272. #ifdef SIGINFO
  273. info_in += r;
  274. #endif
  275. if (iswap != NULL)
  276. iswap(iau.au_enc, ib, r);
  277. if ((t = conv(iau.au_enc, ib, r, oau.au_enc, ob,
  278. obsize, 0)) < 0)
  279. abort();
  280. if (oswap != NULL)
  281. oswap(oau.au_enc, ob, t);
  282. if (nwrite(STDOUT_FILENO, ob, t) != t) {
  283. if (iau.au_size != UINT32_MAX)
  284. err(EX_IOERR,
  285. "Write error");
  286. goto ret;
  287. }
  288. #ifdef SIGINFO
  289. info_out += t;
  290. #endif
  291. if (iau.au_size != UINT32_MAX)
  292. iau.au_size -= r;
  293. }
  294. if (r < 0)
  295. err(EX_IOERR, "Error reading from the "
  296. "standard input");
  297. if (imode == MODE_RAW)
  298. break;
  299. if (imode == MODE_NOHDR)
  300. imode = MODE_AU;
  301. }
  302. ret:
  303. if (ib != NULL)
  304. free(ib);
  305. if (ob != NULL)
  306. free(ob);
  307. return (EX_OK);
  308. usage:
  309. (void)fprintf(stderr,
  310. "usage: auconv "
  311. "[-b buffer-size] [-c channels] [-i input-encoding]\n"
  312. " "
  313. "[-j skip] [-o output-encoding] [-r rate] [-s size]\n");
  314. return (EX_USAGE);
  315. }
  316. #ifdef SIGINFO
  317. void
  318. siginfo(int sig)
  319. {
  320. /* auconv: XXXXXXiB in XXXXXXiB out */
  321. char b[8 + 8 + 4 + 8 + 5];
  322. size_t i = 0;
  323. (void)memcpy(b + i, "auconv: ", 8);
  324. i += 8;
  325. (void)memcpy(b + i, ": ", 2);
  326. i += 2;
  327. i += szwrite(b + i, info_in, "B", "iB");
  328. (void)memcpy(b + i, " in ", 4);
  329. i += 4;
  330. i += szwrite(b + i, info_out, "B", "iB");
  331. (void)memcpy(b + i, " out\n ", 5);
  332. i += 5;
  333. (void)write(STDERR_FILENO, b, i);
  334. }
  335. #endif
  336. size_t
  337. conv(uint32_t ienc, const void *ib, size_t isize, uint32_t oenc,
  338. void *ob, size_t osize, size_t skip)
  339. {
  340. size_t i;
  341. size_t j = 0;
  342. size_t o;
  343. size_t off;
  344. assert(ib != NULL && ob != NULL);
  345. if (osize == 0)
  346. return (0);
  347. o = au_encsize(ienc);
  348. off = o + o * skip;
  349. if (ienc == oenc) {
  350. if (off == o) {
  351. i = isize > osize ? osize : isize;
  352. (void)memmove(ob, ib, i);
  353. return (i);
  354. }
  355. for (i = 0, j = 0; i < isize && j < osize;
  356. i += off, j += o)
  357. (void)memmove((void *)((uintptr_t)ob + j),
  358. (void *)((uintptr_t)ib + i), o);
  359. }
  360. switch (ienc) {
  361. case AU_ULAW:
  362. for (i = 0, j = 0; i < isize && j < osize; i += off)
  363. j += ulawconv(*(uint8_t *)((uintptr_t)ib + i),
  364. (void *)((uintptr_t)ob + j), oenc);
  365. break;
  366. case AU_PCM8:
  367. /* FALLTHROUGH */
  368. case AU_PCM16:
  369. /* FALLTHROUGH */
  370. case AU_PCM24:
  371. /* FALLTHROUGH */
  372. case AU_PCM32:
  373. for (i = 0, j = 0; i < isize && j < osize; i += off)
  374. j += pcmconv((void *)((uintptr_t)ib + i), o,
  375. (void *)((uintptr_t)ob + j), oenc);
  376. break;
  377. case AU_FLOAT32:
  378. /* FALLTHROUGH */
  379. case AU_FLOAT64:
  380. for (i = 0, j = 0; i < isize && j < osize; i += off)
  381. j += floatconv((void *)((uintptr_t)ib + i), o,
  382. (void *)((uintptr_t)ob + j), oenc);
  383. break;
  384. case AU_ALAW:
  385. for (i = 0, j = 0; i < isize && j < osize; i += off)
  386. j += alawconv(*(uint8_t *)((uintptr_t)ib + i),
  387. (void *)((uintptr_t)ob + j), oenc);
  388. break;
  389. }
  390. return (j);
  391. }
  392. size_t
  393. pcmconv(void *ib, size_t io, void *ob, uint32_t oenc)
  394. {
  395. const uint32_t end = 1;
  396. char b[sizeof(double)];
  397. size_t i;
  398. size_t t;
  399. uint32_t pcm;
  400. switch (oenc) {
  401. case AU_ULAW:
  402. if (io == 1) { /* expand to 14-bits */
  403. pcm = *(uint8_t *)ib;
  404. pcm = (pcm << 6) | (pcm >> 2);
  405. } else /* shrink to 14-bits */
  406. pcm = (((uint8_t *)ib)[0] << 6) |
  407. (((uint8_t *)ib)[1] >> 2);
  408. if (pcm & 0x2000) {
  409. pcm = ~pcm & 0x1FFF;
  410. i = 0;
  411. } else
  412. i = 0x80;
  413. if (pcm < 0x2000 - 33)
  414. pcm += 33;
  415. t = clz_16(pcm) - 3;
  416. *(uint8_t *)ob = i | (t << 4) |
  417. (~(pcm >> (8 - t)) & 0x0F);
  418. return (1);
  419. case AU_PCM8:
  420. /* FALLTHROUGH */
  421. case AU_PCM16:
  422. /* FALLTHROUGH */
  423. case AU_PCM24:
  424. /* FALLTHROUGH */
  425. case AU_PCM32:
  426. for (i = 0, t = au_encsize(oenc); i < t; i++)
  427. ((uint8_t *)ob)[i] = ((uint8_t *)ib)[i % io];
  428. return (t);
  429. case AU_FLOAT32:
  430. /* FALLTHROUGH */
  431. case AU_FLOAT64:
  432. for (i = 0, pcm = 0; i < io; i++)
  433. pcm = pcm << 8 | ((uint8_t *)ib)[i];
  434. t = UINT32_C(1) << ((io * 8) - 1);
  435. if (pcm & t) {
  436. pcm = (~pcm & (t - 1)) + 1;
  437. i = 0;
  438. } else
  439. i = 1;
  440. if (oenc == AU_FLOAT32) {
  441. *(float *)b = (float)pcm / (float)(t - i);
  442. if (!i)
  443. *(float *)b = -*(float *)b;
  444. t = sizeof(float);
  445. } else {
  446. *(double *)b = (double)pcm / (double)(t - i);
  447. if (!i)
  448. *(double *)b = -*(double *)b;
  449. t = sizeof(double);
  450. }
  451. if (*(char *)&end)
  452. for (i = 0; i < t; i++)
  453. ((char *)ob)[i] = b[t - i - 1];
  454. else
  455. for (i = 0; i < t; i++)
  456. ((char *)ob)[i] = b[i];
  457. return (t);
  458. case AU_ALAW:
  459. if (io == 1) { /* expand to 13-bits */
  460. pcm = *(uint8_t *)ib;
  461. pcm = (pcm << 5) | (pcm >> 3);
  462. } else /* shrink to 13-bits */
  463. pcm = (((uint8_t *)ib)[0] << 5) |
  464. (((uint8_t *)ib)[1] >> 3);
  465. if (pcm & 0x1000) {
  466. pcm = ~pcm & 0x0FFF;
  467. i = 0;
  468. } else
  469. i = 0x80;
  470. if ((t = clz_16(pcm) - 4) >= 7)
  471. *(uint8_t *)ob = i | ((pcm >> 1) & 0x0F);
  472. else
  473. *(uint8_t *)ob = i | ((7 - t) << 4) |
  474. ((pcm >> (7 - t)) & 0x0F);
  475. *(uint8_t *)ob ^= 0x55;
  476. return (1);
  477. }
  478. abort();
  479. }
  480. size_t
  481. ulawconv(uint8_t u, void *ob, uint32_t oenc)
  482. {
  483. unsigned char b[sizeof(uint16_t)];
  484. uint16_t pcm;
  485. uint16_t p;
  486. if (oenc == AU_ULAW) {
  487. *(uint8_t *)ob = u;
  488. return (1);
  489. }
  490. u = ~u;
  491. p = (u >> 4) & 7;
  492. pcm = ((u & 0x0F) << (p + 1)) | (0x21 << p);
  493. pcm = ((pcm << 2) | (pcm >> 12)) - 33;
  494. if (u & 0x80)
  495. pcm = ~pcm;
  496. for (p = 0; p < sizeof(b); p++)
  497. b[p] = pcm >> (sizeof(b) - p - 1) * CHAR_BIT;
  498. return (pcmconv(b, sizeof(uint16_t), ob, oenc));
  499. }
  500. size_t
  501. alawconv(uint8_t a, void *ob, uint32_t oenc)
  502. {
  503. unsigned char b[sizeof(uint16_t)];
  504. uint16_t pcm;
  505. uint16_t p;
  506. if (oenc == AU_ALAW) {
  507. *(uint8_t *)ob = a;
  508. return (1);
  509. }
  510. a ^= 0xD5;
  511. if ((p = (a >> 4) & 7) == 0)
  512. pcm = ((a & 0x0F) << 1) | 1;
  513. else
  514. pcm = ((a & 0x0F) << p) | (0x21 << (p - 1));
  515. pcm = (pcm << 3) | (pcm >> 10);
  516. if (a & 0x80)
  517. pcm = ~pcm;
  518. for (p = 0; p < sizeof(b); p++)
  519. b[p] = pcm >> (sizeof(b) - p - 1) * CHAR_BIT;
  520. return (pcmconv(b, sizeof(uint16_t), ob, oenc));
  521. }
  522. size_t
  523. floatconv(void *ib, size_t io, void *ob, uint32_t oenc)
  524. {
  525. const uint32_t end = 1;
  526. unsigned char b[sizeof(double)];
  527. uint32_t pcm;
  528. uint32_t t = 0;
  529. double d;
  530. size_t i;
  531. /* and begin incantations */
  532. switch (oenc) {
  533. case AU_ULAW:
  534. (void)floatconv(ib, io, b, AU_PCM16);
  535. return (pcmconv(b, sizeof(uint16_t), ob, oenc));
  536. break;
  537. case AU_PCM8:
  538. /* FALLTHROUGH */
  539. case AU_PCM16:
  540. /* FALLTHROUGH */
  541. case AU_PCM24:
  542. /* FALLTHROUGH */
  543. case AU_PCM32:
  544. t = oenc - AU_PCM8 + 1;
  545. if (*(char *)&end)
  546. for (i = 0; i < io; i++)
  547. b[i] = ((char *)ib)[io - i - 1];
  548. else
  549. for (i = 0; i < io; i++)
  550. b[i] = ((char *)ib)[i];
  551. if (io == sizeof(float))
  552. d = *(float *)b;
  553. else
  554. d = *(double *)b;
  555. if (d < 0) {
  556. d = -d;
  557. i = 0;
  558. } else
  559. i = 1;
  560. d *= (UINT32_C(1) << (t * 8 - 1)) - i;
  561. pcm = (uint32_t)d;
  562. if (!i)
  563. pcm = ~pcm + 1;
  564. for (i = 0; i < t; i++)
  565. ((uint8_t *)ob)[i] = pcm >> (t - i - 1) * 8;
  566. return (t);
  567. case AU_FLOAT32:
  568. if (io == sizeof(float)) {
  569. (void)memcpy(ob, ib, io);
  570. return (io);
  571. }
  572. /*
  573. * Expanded Float Double
  574. * sabcdefg sabcdefg
  575. * mantissa loop -> habc*123 hijk0123
  576. * 45670123 45670123
  577. * 45670123 45670123
  578. * mantissa loop -> 456*1234 45670123
  579. * 56701234 45670123
  580. * 56701234 45670123
  581. * mantissa loop -> 56*12345 45670123
  582. */
  583. ((uint8_t *)ob)[0] = ((uint8_t *)ib)[0];
  584. ((uint8_t *)ob)[1] = (((uint8_t *)ib)[1] & 0x80) |
  585. (((uint8_t *)ob)[0] & 0x70) |
  586. ((((uint8_t *)ib)[1] >> 3) & 0x0F);
  587. ((uint8_t *)ob)[2] = (((uint8_t *)ib)[1] << 5) |
  588. ((((uint8_t *)ib)[2] >> 3) & 0x1F);
  589. ((uint8_t *)ob)[3] = (((uint8_t *)ib)[2] << 5) |
  590. ((((uint8_t *)ib)[3] >> 3) & 0x1F);
  591. ((uint8_t *)ob)[4] = (((uint8_t *)ib)[3] << 5) |
  592. ((((uint8_t *)ib)[1] >> 2) & 0x1F);
  593. ((uint8_t *)ob)[5] = (((uint8_t *)ib)[1] << 6) |
  594. ((((uint8_t *)ib)[2] >> 2) & 0x1F);
  595. ((uint8_t *)ob)[6] = (((uint8_t *)ib)[2] << 6) |
  596. ((((uint8_t *)ib)[3] >> 2) & 0x1F);
  597. ((uint8_t *)ob)[7] = (((uint8_t *)ib)[3] << 6) |
  598. ((((uint8_t *)ib)[1] >> 1) & 0x1F);
  599. return (sizeof(double));
  600. case AU_FLOAT64:
  601. if (io == sizeof(double)) {
  602. (void)memcpy(ob, ib, io);
  603. return (io);
  604. }
  605. ((uint8_t *)ob)[0] = ((uint8_t *)ib)[0];
  606. ((uint8_t *)ob)[1] = (((uint8_t *)ib)[1] & 0x80) |
  607. ((((uint8_t *)ib)[1] << 3) & 0x70) |
  608. (((uint8_t *)ib)[2] >> 5);
  609. ((uint8_t *)ob)[2] = (((uint8_t *)ib)[2] << 3) |
  610. (((uint8_t *)ib)[3] >> 5);
  611. ((uint8_t *)ob)[3] = (((uint8_t *)ib)[3] << 3) |
  612. (((uint8_t *)ib)[4] >> 5);
  613. return (sizeof(float));
  614. case AU_ALAW:
  615. (void)floatconv(ib, io, b, AU_PCM16);
  616. return (pcmconv(b, sizeof(uint16_t), ob, oenc));
  617. break;
  618. }
  619. abort();
  620. }
  621. ssize_t
  622. ncpy(int in, int out, void *b, size_t s)
  623. {
  624. ssize_t t;
  625. if ((t = nread(in, b, s)) > 0) {
  626. #ifdef SIGINFO
  627. info_in += t;
  628. #endif
  629. t = nwrite(out, b, s);
  630. #ifdef SIGINFO
  631. info_out += t;
  632. #endif
  633. }
  634. return (t);
  635. }
  636. unsigned
  637. clz_16(uint16_t v)
  638. {
  639. unsigned r = 0;
  640. if ((v & 0xFF00) == 0) {
  641. v <<= 8;
  642. r += 8;
  643. }
  644. if ((v & 0xF000) == 0) {
  645. v <<= 4;
  646. r += 4;
  647. }
  648. if ((v & 0xC000) == 0) {
  649. v <<= 2;
  650. r += 2;
  651. }
  652. r += (uint16_t)~v >> 15;
  653. return (r);
  654. }