pcm_misc.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
  1. /*
  2. * PCM Interface - misc routines
  3. * Copyright (c) 1998 by Jaroslav Kysela <perex@perex.cz>
  4. *
  5. *
  6. * This library is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU Library General Public License as
  8. * published by the Free Software Foundation; either version 2 of
  9. * the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU Library General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Library General Public
  17. * License along with this library; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. *
  20. */
  21. #include <linux/time.h>
  22. #include <sound/core.h>
  23. #include <sound/pcm.h>
  24. #define SND_PCM_FORMAT_UNKNOWN (-1)
  25. /* NOTE: "signed" prefix must be given below since the default char is
  26. * unsigned on some architectures!
  27. */
  28. struct pcm_format_data {
  29. unsigned char width; /* bit width */
  30. unsigned char phys; /* physical bit width */
  31. signed char le; /* 0 = big-endian, 1 = little-endian, -1 = others */
  32. signed char signd; /* 0 = unsigned, 1 = signed, -1 = others */
  33. unsigned char silence[8]; /* silence data to fill */
  34. };
  35. /* we do lots of calculations on snd_pcm_format_t; shut up sparse */
  36. #define INT __force int
  37. static struct pcm_format_data pcm_formats[(INT)SNDRV_PCM_FORMAT_LAST+1] = {
  38. [SNDRV_PCM_FORMAT_S8] = {
  39. .width = 8, .phys = 8, .le = -1, .signd = 1,
  40. .silence = {},
  41. },
  42. [SNDRV_PCM_FORMAT_U8] = {
  43. .width = 8, .phys = 8, .le = -1, .signd = 0,
  44. .silence = { 0x80 },
  45. },
  46. [SNDRV_PCM_FORMAT_S16_LE] = {
  47. .width = 16, .phys = 16, .le = 1, .signd = 1,
  48. .silence = {},
  49. },
  50. [SNDRV_PCM_FORMAT_S16_BE] = {
  51. .width = 16, .phys = 16, .le = 0, .signd = 1,
  52. .silence = {},
  53. },
  54. [SNDRV_PCM_FORMAT_U16_LE] = {
  55. .width = 16, .phys = 16, .le = 1, .signd = 0,
  56. .silence = { 0x00, 0x80 },
  57. },
  58. [SNDRV_PCM_FORMAT_U16_BE] = {
  59. .width = 16, .phys = 16, .le = 0, .signd = 0,
  60. .silence = { 0x80, 0x00 },
  61. },
  62. [SNDRV_PCM_FORMAT_S24_LE] = {
  63. .width = 24, .phys = 32, .le = 1, .signd = 1,
  64. .silence = {},
  65. },
  66. [SNDRV_PCM_FORMAT_S24_BE] = {
  67. .width = 24, .phys = 32, .le = 0, .signd = 1,
  68. .silence = {},
  69. },
  70. [SNDRV_PCM_FORMAT_U24_LE] = {
  71. .width = 24, .phys = 32, .le = 1, .signd = 0,
  72. .silence = { 0x00, 0x00, 0x80 },
  73. },
  74. [SNDRV_PCM_FORMAT_U24_BE] = {
  75. .width = 24, .phys = 32, .le = 0, .signd = 0,
  76. .silence = { 0x00, 0x80, 0x00, 0x00 },
  77. },
  78. [SNDRV_PCM_FORMAT_S32_LE] = {
  79. .width = 32, .phys = 32, .le = 1, .signd = 1,
  80. .silence = {},
  81. },
  82. [SNDRV_PCM_FORMAT_S32_BE] = {
  83. .width = 32, .phys = 32, .le = 0, .signd = 1,
  84. .silence = {},
  85. },
  86. [SNDRV_PCM_FORMAT_U32_LE] = {
  87. .width = 32, .phys = 32, .le = 1, .signd = 0,
  88. .silence = { 0x00, 0x00, 0x00, 0x80 },
  89. },
  90. [SNDRV_PCM_FORMAT_U32_BE] = {
  91. .width = 32, .phys = 32, .le = 0, .signd = 0,
  92. .silence = { 0x80, 0x00, 0x00, 0x00 },
  93. },
  94. [SNDRV_PCM_FORMAT_FLOAT_LE] = {
  95. .width = 32, .phys = 32, .le = 1, .signd = -1,
  96. .silence = {},
  97. },
  98. [SNDRV_PCM_FORMAT_FLOAT_BE] = {
  99. .width = 32, .phys = 32, .le = 0, .signd = -1,
  100. .silence = {},
  101. },
  102. [SNDRV_PCM_FORMAT_FLOAT64_LE] = {
  103. .width = 64, .phys = 64, .le = 1, .signd = -1,
  104. .silence = {},
  105. },
  106. [SNDRV_PCM_FORMAT_FLOAT64_BE] = {
  107. .width = 64, .phys = 64, .le = 0, .signd = -1,
  108. .silence = {},
  109. },
  110. [SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE] = {
  111. .width = 32, .phys = 32, .le = 1, .signd = -1,
  112. .silence = {},
  113. },
  114. [SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE] = {
  115. .width = 32, .phys = 32, .le = 0, .signd = -1,
  116. .silence = {},
  117. },
  118. [SNDRV_PCM_FORMAT_MU_LAW] = {
  119. .width = 8, .phys = 8, .le = -1, .signd = -1,
  120. .silence = { 0x7f },
  121. },
  122. [SNDRV_PCM_FORMAT_A_LAW] = {
  123. .width = 8, .phys = 8, .le = -1, .signd = -1,
  124. .silence = { 0x55 },
  125. },
  126. [SNDRV_PCM_FORMAT_IMA_ADPCM] = {
  127. .width = 4, .phys = 4, .le = -1, .signd = -1,
  128. .silence = {},
  129. },
  130. [SNDRV_PCM_FORMAT_G723_24] = {
  131. .width = 3, .phys = 3, .le = -1, .signd = -1,
  132. .silence = {},
  133. },
  134. [SNDRV_PCM_FORMAT_G723_40] = {
  135. .width = 5, .phys = 5, .le = -1, .signd = -1,
  136. .silence = {},
  137. },
  138. /* FIXME: the following three formats are not defined properly yet */
  139. [SNDRV_PCM_FORMAT_MPEG] = {
  140. .le = -1, .signd = -1,
  141. },
  142. [SNDRV_PCM_FORMAT_GSM] = {
  143. .le = -1, .signd = -1,
  144. },
  145. [SNDRV_PCM_FORMAT_SPECIAL] = {
  146. .le = -1, .signd = -1,
  147. },
  148. [SNDRV_PCM_FORMAT_S24_3LE] = {
  149. .width = 24, .phys = 24, .le = 1, .signd = 1,
  150. .silence = {},
  151. },
  152. [SNDRV_PCM_FORMAT_S24_3BE] = {
  153. .width = 24, .phys = 24, .le = 0, .signd = 1,
  154. .silence = {},
  155. },
  156. [SNDRV_PCM_FORMAT_U24_3LE] = {
  157. .width = 24, .phys = 24, .le = 1, .signd = 0,
  158. .silence = { 0x00, 0x00, 0x80 },
  159. },
  160. [SNDRV_PCM_FORMAT_U24_3BE] = {
  161. .width = 24, .phys = 24, .le = 0, .signd = 0,
  162. .silence = { 0x80, 0x00, 0x00 },
  163. },
  164. [SNDRV_PCM_FORMAT_S20_3LE] = {
  165. .width = 20, .phys = 24, .le = 1, .signd = 1,
  166. .silence = {},
  167. },
  168. [SNDRV_PCM_FORMAT_S20_3BE] = {
  169. .width = 20, .phys = 24, .le = 0, .signd = 1,
  170. .silence = {},
  171. },
  172. [SNDRV_PCM_FORMAT_U20_3LE] = {
  173. .width = 20, .phys = 24, .le = 1, .signd = 0,
  174. .silence = { 0x00, 0x00, 0x08 },
  175. },
  176. [SNDRV_PCM_FORMAT_U20_3BE] = {
  177. .width = 20, .phys = 24, .le = 0, .signd = 0,
  178. .silence = { 0x08, 0x00, 0x00 },
  179. },
  180. [SNDRV_PCM_FORMAT_S18_3LE] = {
  181. .width = 18, .phys = 24, .le = 1, .signd = 1,
  182. .silence = {},
  183. },
  184. [SNDRV_PCM_FORMAT_S18_3BE] = {
  185. .width = 18, .phys = 24, .le = 0, .signd = 1,
  186. .silence = {},
  187. },
  188. [SNDRV_PCM_FORMAT_U18_3LE] = {
  189. .width = 18, .phys = 24, .le = 1, .signd = 0,
  190. .silence = { 0x00, 0x00, 0x02 },
  191. },
  192. [SNDRV_PCM_FORMAT_U18_3BE] = {
  193. .width = 18, .phys = 24, .le = 0, .signd = 0,
  194. .silence = { 0x02, 0x00, 0x00 },
  195. },
  196. [SNDRV_PCM_FORMAT_G723_24_1B] = {
  197. .width = 3, .phys = 8, .le = -1, .signd = -1,
  198. .silence = {},
  199. },
  200. [SNDRV_PCM_FORMAT_G723_40_1B] = {
  201. .width = 5, .phys = 8, .le = -1, .signd = -1,
  202. .silence = {},
  203. },
  204. };
  205. /**
  206. * snd_pcm_format_signed - Check the PCM format is signed linear
  207. * @format: the format to check
  208. *
  209. * Returns 1 if the given PCM format is signed linear, 0 if unsigned
  210. * linear, and a negative error code for non-linear formats.
  211. */
  212. int snd_pcm_format_signed(snd_pcm_format_t format)
  213. {
  214. int val;
  215. if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST)
  216. return -EINVAL;
  217. if ((val = pcm_formats[(INT)format].signd) < 0)
  218. return -EINVAL;
  219. return val;
  220. }
  221. EXPORT_SYMBOL(snd_pcm_format_signed);
  222. /**
  223. * snd_pcm_format_unsigned - Check the PCM format is unsigned linear
  224. * @format: the format to check
  225. *
  226. * Returns 1 if the given PCM format is unsigned linear, 0 if signed
  227. * linear, and a negative error code for non-linear formats.
  228. */
  229. int snd_pcm_format_unsigned(snd_pcm_format_t format)
  230. {
  231. int val;
  232. val = snd_pcm_format_signed(format);
  233. if (val < 0)
  234. return val;
  235. return !val;
  236. }
  237. EXPORT_SYMBOL(snd_pcm_format_unsigned);
  238. /**
  239. * snd_pcm_format_linear - Check the PCM format is linear
  240. * @format: the format to check
  241. *
  242. * Returns 1 if the given PCM format is linear, 0 if not.
  243. */
  244. int snd_pcm_format_linear(snd_pcm_format_t format)
  245. {
  246. return snd_pcm_format_signed(format) >= 0;
  247. }
  248. EXPORT_SYMBOL(snd_pcm_format_linear);
  249. /**
  250. * snd_pcm_format_little_endian - Check the PCM format is little-endian
  251. * @format: the format to check
  252. *
  253. * Returns 1 if the given PCM format is little-endian, 0 if
  254. * big-endian, or a negative error code if endian not specified.
  255. */
  256. int snd_pcm_format_little_endian(snd_pcm_format_t format)
  257. {
  258. int val;
  259. if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST)
  260. return -EINVAL;
  261. if ((val = pcm_formats[(INT)format].le) < 0)
  262. return -EINVAL;
  263. return val;
  264. }
  265. EXPORT_SYMBOL(snd_pcm_format_little_endian);
  266. /**
  267. * snd_pcm_format_big_endian - Check the PCM format is big-endian
  268. * @format: the format to check
  269. *
  270. * Returns 1 if the given PCM format is big-endian, 0 if
  271. * little-endian, or a negative error code if endian not specified.
  272. */
  273. int snd_pcm_format_big_endian(snd_pcm_format_t format)
  274. {
  275. int val;
  276. val = snd_pcm_format_little_endian(format);
  277. if (val < 0)
  278. return val;
  279. return !val;
  280. }
  281. EXPORT_SYMBOL(snd_pcm_format_big_endian);
  282. /**
  283. * snd_pcm_format_width - return the bit-width of the format
  284. * @format: the format to check
  285. *
  286. * Returns the bit-width of the format, or a negative error code
  287. * if unknown format.
  288. */
  289. int snd_pcm_format_width(snd_pcm_format_t format)
  290. {
  291. int val;
  292. if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST)
  293. return -EINVAL;
  294. if ((val = pcm_formats[(INT)format].width) == 0)
  295. return -EINVAL;
  296. return val;
  297. }
  298. EXPORT_SYMBOL(snd_pcm_format_width);
  299. /**
  300. * snd_pcm_format_physical_width - return the physical bit-width of the format
  301. * @format: the format to check
  302. *
  303. * Returns the physical bit-width of the format, or a negative error code
  304. * if unknown format.
  305. */
  306. int snd_pcm_format_physical_width(snd_pcm_format_t format)
  307. {
  308. int val;
  309. if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST)
  310. return -EINVAL;
  311. if ((val = pcm_formats[(INT)format].phys) == 0)
  312. return -EINVAL;
  313. return val;
  314. }
  315. EXPORT_SYMBOL(snd_pcm_format_physical_width);
  316. /**
  317. * snd_pcm_format_size - return the byte size of samples on the given format
  318. * @format: the format to check
  319. * @samples: sampling rate
  320. *
  321. * Returns the byte size of the given samples for the format, or a
  322. * negative error code if unknown format.
  323. */
  324. ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples)
  325. {
  326. int phys_width = snd_pcm_format_physical_width(format);
  327. if (phys_width < 0)
  328. return -EINVAL;
  329. return samples * phys_width / 8;
  330. }
  331. EXPORT_SYMBOL(snd_pcm_format_size);
  332. /**
  333. * snd_pcm_format_silence_64 - return the silent data in 8 bytes array
  334. * @format: the format to check
  335. *
  336. * Returns the format pattern to fill or NULL if error.
  337. */
  338. const unsigned char *snd_pcm_format_silence_64(snd_pcm_format_t format)
  339. {
  340. if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST)
  341. return NULL;
  342. if (! pcm_formats[(INT)format].phys)
  343. return NULL;
  344. return pcm_formats[(INT)format].silence;
  345. }
  346. EXPORT_SYMBOL(snd_pcm_format_silence_64);
  347. /**
  348. * snd_pcm_format_set_silence - set the silence data on the buffer
  349. * @format: the PCM format
  350. * @data: the buffer pointer
  351. * @samples: the number of samples to set silence
  352. *
  353. * Sets the silence data on the buffer for the given samples.
  354. *
  355. * Returns zero if successful, or a negative error code on failure.
  356. */
  357. int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int samples)
  358. {
  359. int width;
  360. unsigned char *dst, *pat;
  361. if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST)
  362. return -EINVAL;
  363. if (samples == 0)
  364. return 0;
  365. width = pcm_formats[(INT)format].phys; /* physical width */
  366. pat = pcm_formats[(INT)format].silence;
  367. if (! width)
  368. return -EINVAL;
  369. /* signed or 1 byte data */
  370. if (pcm_formats[(INT)format].signd == 1 || width <= 8) {
  371. unsigned int bytes = samples * width / 8;
  372. memset(data, *pat, bytes);
  373. return 0;
  374. }
  375. /* non-zero samples, fill using a loop */
  376. width /= 8;
  377. dst = data;
  378. #if 0
  379. while (samples--) {
  380. memcpy(dst, pat, width);
  381. dst += width;
  382. }
  383. #else
  384. /* a bit optimization for constant width */
  385. switch (width) {
  386. case 2:
  387. while (samples--) {
  388. memcpy(dst, pat, 2);
  389. dst += 2;
  390. }
  391. break;
  392. case 3:
  393. while (samples--) {
  394. memcpy(dst, pat, 3);
  395. dst += 3;
  396. }
  397. break;
  398. case 4:
  399. while (samples--) {
  400. memcpy(dst, pat, 4);
  401. dst += 4;
  402. }
  403. break;
  404. case 8:
  405. while (samples--) {
  406. memcpy(dst, pat, 8);
  407. dst += 8;
  408. }
  409. break;
  410. }
  411. #endif
  412. return 0;
  413. }
  414. EXPORT_SYMBOL(snd_pcm_format_set_silence);
  415. /**
  416. * snd_pcm_limit_hw_rates - determine rate_min/rate_max fields
  417. * @runtime: the runtime instance
  418. *
  419. * Determines the rate_min and rate_max fields from the rates bits of
  420. * the given runtime->hw.
  421. *
  422. * Returns zero if successful.
  423. */
  424. int snd_pcm_limit_hw_rates(struct snd_pcm_runtime *runtime)
  425. {
  426. int i;
  427. for (i = 0; i < (int)snd_pcm_known_rates.count; i++) {
  428. if (runtime->hw.rates & (1 << i)) {
  429. runtime->hw.rate_min = snd_pcm_known_rates.list[i];
  430. break;
  431. }
  432. }
  433. for (i = (int)snd_pcm_known_rates.count - 1; i >= 0; i--) {
  434. if (runtime->hw.rates & (1 << i)) {
  435. runtime->hw.rate_max = snd_pcm_known_rates.list[i];
  436. break;
  437. }
  438. }
  439. return 0;
  440. }
  441. EXPORT_SYMBOL(snd_pcm_limit_hw_rates);
  442. /**
  443. * snd_pcm_rate_to_rate_bit - converts sample rate to SNDRV_PCM_RATE_xxx bit
  444. * @rate: the sample rate to convert
  445. *
  446. * Returns the SNDRV_PCM_RATE_xxx flag that corresponds to the given rate, or
  447. * SNDRV_PCM_RATE_KNOT for an unknown rate.
  448. */
  449. unsigned int snd_pcm_rate_to_rate_bit(unsigned int rate)
  450. {
  451. unsigned int i;
  452. for (i = 0; i < snd_pcm_known_rates.count; i++)
  453. if (snd_pcm_known_rates.list[i] == rate)
  454. return 1u << i;
  455. return SNDRV_PCM_RATE_KNOT;
  456. }
  457. EXPORT_SYMBOL(snd_pcm_rate_to_rate_bit);