xref: /linux/sound/core/pcm_misc.c (revision bc1d4e705f48f001f3a5480f04067c48bd00bcf0)
1 // SPDX-License-Identifier: LGPL-2.0+
2 /*
3  *  PCM Interface - misc routines
4  *  Copyright (c) 1998 by Jaroslav Kysela <perex@perex.cz>
5  */
6 
7 #include <linux/time.h>
8 #include <linux/export.h>
9 #include <sound/core.h>
10 #include <sound/pcm.h>
11 
12 #include "pcm_local.h"
13 
14 #define SND_PCM_FORMAT_UNKNOWN (-1)
15 
16 /* NOTE: "signed" prefix must be given below since the default char is
17  *       unsigned on some architectures!
18  */
19 struct pcm_format_data {
20 	unsigned char width;	/* bit width */
21 	unsigned char phys;	/* physical bit width */
22 	signed char le;	/* 0 = big-endian, 1 = little-endian, -1 = others */
23 	signed char signd;	/* 0 = unsigned, 1 = signed, -1 = others */
24 	unsigned char silence[8];	/* silence data to fill */
25 };
26 
27 /* we do lots of calculations on snd_pcm_format_t; shut up sparse */
28 #define INT	__force int
29 
valid_format(snd_pcm_format_t format)30 static bool valid_format(snd_pcm_format_t format)
31 {
32 	return (INT)format >= 0 && (INT)format <= (INT)SNDRV_PCM_FORMAT_LAST;
33 }
34 
35 static const struct pcm_format_data pcm_formats[(INT)SNDRV_PCM_FORMAT_LAST+1] = {
36 	[SNDRV_PCM_FORMAT_S8] = {
37 		.width = 8, .phys = 8, .le = -1, .signd = 1,
38 		.silence = {},
39 	},
40 	[SNDRV_PCM_FORMAT_U8] = {
41 		.width = 8, .phys = 8, .le = -1, .signd = 0,
42 		.silence = { 0x80 },
43 	},
44 	[SNDRV_PCM_FORMAT_S16_LE] = {
45 		.width = 16, .phys = 16, .le = 1, .signd = 1,
46 		.silence = {},
47 	},
48 	[SNDRV_PCM_FORMAT_S16_BE] = {
49 		.width = 16, .phys = 16, .le = 0, .signd = 1,
50 		.silence = {},
51 	},
52 	[SNDRV_PCM_FORMAT_U16_LE] = {
53 		.width = 16, .phys = 16, .le = 1, .signd = 0,
54 		.silence = { 0x00, 0x80 },
55 	},
56 	[SNDRV_PCM_FORMAT_U16_BE] = {
57 		.width = 16, .phys = 16, .le = 0, .signd = 0,
58 		.silence = { 0x80, 0x00 },
59 	},
60 	[SNDRV_PCM_FORMAT_S24_LE] = {
61 		.width = 24, .phys = 32, .le = 1, .signd = 1,
62 		.silence = {},
63 	},
64 	[SNDRV_PCM_FORMAT_S24_BE] = {
65 		.width = 24, .phys = 32, .le = 0, .signd = 1,
66 		.silence = {},
67 	},
68 	[SNDRV_PCM_FORMAT_U24_LE] = {
69 		.width = 24, .phys = 32, .le = 1, .signd = 0,
70 		.silence = { 0x00, 0x00, 0x80 },
71 	},
72 	[SNDRV_PCM_FORMAT_U24_BE] = {
73 		.width = 24, .phys = 32, .le = 0, .signd = 0,
74 		.silence = { 0x00, 0x80, 0x00, 0x00 },
75 	},
76 	[SNDRV_PCM_FORMAT_S32_LE] = {
77 		.width = 32, .phys = 32, .le = 1, .signd = 1,
78 		.silence = {},
79 	},
80 	[SNDRV_PCM_FORMAT_S32_BE] = {
81 		.width = 32, .phys = 32, .le = 0, .signd = 1,
82 		.silence = {},
83 	},
84 	[SNDRV_PCM_FORMAT_U32_LE] = {
85 		.width = 32, .phys = 32, .le = 1, .signd = 0,
86 		.silence = { 0x00, 0x00, 0x00, 0x80 },
87 	},
88 	[SNDRV_PCM_FORMAT_U32_BE] = {
89 		.width = 32, .phys = 32, .le = 0, .signd = 0,
90 		.silence = { 0x80, 0x00, 0x00, 0x00 },
91 	},
92 	[SNDRV_PCM_FORMAT_FLOAT_LE] = {
93 		.width = 32, .phys = 32, .le = 1, .signd = -1,
94 		.silence = {},
95 	},
96 	[SNDRV_PCM_FORMAT_FLOAT_BE] = {
97 		.width = 32, .phys = 32, .le = 0, .signd = -1,
98 		.silence = {},
99 	},
100 	[SNDRV_PCM_FORMAT_FLOAT64_LE] = {
101 		.width = 64, .phys = 64, .le = 1, .signd = -1,
102 		.silence = {},
103 	},
104 	[SNDRV_PCM_FORMAT_FLOAT64_BE] = {
105 		.width = 64, .phys = 64, .le = 0, .signd = -1,
106 		.silence = {},
107 	},
108 	[SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE] = {
109 		.width = 32, .phys = 32, .le = 1, .signd = -1,
110 		.silence = {},
111 	},
112 	[SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE] = {
113 		.width = 32, .phys = 32, .le = 0, .signd = -1,
114 		.silence = {},
115 	},
116 	[SNDRV_PCM_FORMAT_MU_LAW] = {
117 		.width = 8, .phys = 8, .le = -1, .signd = -1,
118 		.silence = { 0x7f },
119 	},
120 	[SNDRV_PCM_FORMAT_A_LAW] = {
121 		.width = 8, .phys = 8, .le = -1, .signd = -1,
122 		.silence = { 0x55 },
123 	},
124 	[SNDRV_PCM_FORMAT_IMA_ADPCM] = {
125 		.width = 4, .phys = 4, .le = -1, .signd = -1,
126 		.silence = {},
127 	},
128 	[SNDRV_PCM_FORMAT_G723_24] = {
129 		.width = 3, .phys = 3, .le = -1, .signd = -1,
130 		.silence = {},
131 	},
132 	[SNDRV_PCM_FORMAT_G723_40] = {
133 		.width = 5, .phys = 5, .le = -1, .signd = -1,
134 		.silence = {},
135 	},
136 	[SNDRV_PCM_FORMAT_DSD_U8] = {
137 		.width = 8, .phys = 8, .le = 1, .signd = 0,
138 		.silence = { 0x69 },
139 	},
140 	[SNDRV_PCM_FORMAT_DSD_U16_LE] = {
141 		.width = 16, .phys = 16, .le = 1, .signd = 0,
142 		.silence = { 0x69, 0x69 },
143 	},
144 	[SNDRV_PCM_FORMAT_DSD_U32_LE] = {
145 		.width = 32, .phys = 32, .le = 1, .signd = 0,
146 		.silence = { 0x69, 0x69, 0x69, 0x69 },
147 	},
148 	[SNDRV_PCM_FORMAT_DSD_U16_BE] = {
149 		.width = 16, .phys = 16, .le = 0, .signd = 0,
150 		.silence = { 0x69, 0x69 },
151 	},
152 	[SNDRV_PCM_FORMAT_DSD_U32_BE] = {
153 		.width = 32, .phys = 32, .le = 0, .signd = 0,
154 		.silence = { 0x69, 0x69, 0x69, 0x69 },
155 	},
156 	/* FIXME: the following two formats are not defined properly yet */
157 	[SNDRV_PCM_FORMAT_MPEG] = {
158 		.le = -1, .signd = -1,
159 	},
160 	[SNDRV_PCM_FORMAT_GSM] = {
161 		.le = -1, .signd = -1,
162 	},
163 	[SNDRV_PCM_FORMAT_S20_LE] = {
164 		.width = 20, .phys = 32, .le = 1, .signd = 1,
165 		.silence = {},
166 	},
167 	[SNDRV_PCM_FORMAT_S20_BE] = {
168 		.width = 20, .phys = 32, .le = 0, .signd = 1,
169 		.silence = {},
170 	},
171 	[SNDRV_PCM_FORMAT_U20_LE] = {
172 		.width = 20, .phys = 32, .le = 1, .signd = 0,
173 		.silence = { 0x00, 0x00, 0x08, 0x00 },
174 	},
175 	[SNDRV_PCM_FORMAT_U20_BE] = {
176 		.width = 20, .phys = 32, .le = 0, .signd = 0,
177 		.silence = { 0x00, 0x08, 0x00, 0x00 },
178 	},
179 	/* FIXME: the following format is not defined properly yet */
180 	[SNDRV_PCM_FORMAT_SPECIAL] = {
181 		.le = -1, .signd = -1,
182 	},
183 	[SNDRV_PCM_FORMAT_S24_3LE] = {
184 		.width = 24, .phys = 24, .le = 1, .signd = 1,
185 		.silence = {},
186 	},
187 	[SNDRV_PCM_FORMAT_S24_3BE] = {
188 		.width = 24, .phys = 24, .le = 0, .signd = 1,
189 		.silence = {},
190 	},
191 	[SNDRV_PCM_FORMAT_U24_3LE] = {
192 		.width = 24, .phys = 24, .le = 1, .signd = 0,
193 		.silence = { 0x00, 0x00, 0x80 },
194 	},
195 	[SNDRV_PCM_FORMAT_U24_3BE] = {
196 		.width = 24, .phys = 24, .le = 0, .signd = 0,
197 		.silence = { 0x80, 0x00, 0x00 },
198 	},
199 	[SNDRV_PCM_FORMAT_S20_3LE] = {
200 		.width = 20, .phys = 24, .le = 1, .signd = 1,
201 		.silence = {},
202 	},
203 	[SNDRV_PCM_FORMAT_S20_3BE] = {
204 		.width = 20, .phys = 24, .le = 0, .signd = 1,
205 		.silence = {},
206 	},
207 	[SNDRV_PCM_FORMAT_U20_3LE] = {
208 		.width = 20, .phys = 24, .le = 1, .signd = 0,
209 		.silence = { 0x00, 0x00, 0x08 },
210 	},
211 	[SNDRV_PCM_FORMAT_U20_3BE] = {
212 		.width = 20, .phys = 24, .le = 0, .signd = 0,
213 		.silence = { 0x08, 0x00, 0x00 },
214 	},
215 	[SNDRV_PCM_FORMAT_S18_3LE] = {
216 		.width = 18, .phys = 24, .le = 1, .signd = 1,
217 		.silence = {},
218 	},
219 	[SNDRV_PCM_FORMAT_S18_3BE] = {
220 		.width = 18, .phys = 24, .le = 0, .signd = 1,
221 		.silence = {},
222 	},
223 	[SNDRV_PCM_FORMAT_U18_3LE] = {
224 		.width = 18, .phys = 24, .le = 1, .signd = 0,
225 		.silence = { 0x00, 0x00, 0x02 },
226 	},
227 	[SNDRV_PCM_FORMAT_U18_3BE] = {
228 		.width = 18, .phys = 24, .le = 0, .signd = 0,
229 		.silence = { 0x02, 0x00, 0x00 },
230 	},
231 	[SNDRV_PCM_FORMAT_G723_24_1B] = {
232 		.width = 3, .phys = 8, .le = -1, .signd = -1,
233 		.silence = {},
234 	},
235 	[SNDRV_PCM_FORMAT_G723_40_1B] = {
236 		.width = 5, .phys = 8, .le = -1, .signd = -1,
237 		.silence = {},
238 	},
239 };
240 
241 
242 /**
243  * snd_pcm_format_signed - Check the PCM format is signed linear
244  * @format: the format to check
245  *
246  * Return: 1 if the given PCM format is signed linear, 0 if unsigned
247  * linear, and a negative error code for non-linear formats.
248  */
snd_pcm_format_signed(snd_pcm_format_t format)249 int snd_pcm_format_signed(snd_pcm_format_t format)
250 {
251 	int val;
252 	if (!valid_format(format))
253 		return -EINVAL;
254 	val = pcm_formats[(INT)format].signd;
255 	if (val < 0)
256 		return -EINVAL;
257 	return val;
258 }
259 EXPORT_SYMBOL(snd_pcm_format_signed);
260 
261 /**
262  * snd_pcm_format_unsigned - Check the PCM format is unsigned linear
263  * @format: the format to check
264  *
265  * Return: 1 if the given PCM format is unsigned linear, 0 if signed
266  * linear, and a negative error code for non-linear formats.
267  */
snd_pcm_format_unsigned(snd_pcm_format_t format)268 int snd_pcm_format_unsigned(snd_pcm_format_t format)
269 {
270 	int val;
271 
272 	val = snd_pcm_format_signed(format);
273 	if (val < 0)
274 		return val;
275 	return !val;
276 }
277 EXPORT_SYMBOL(snd_pcm_format_unsigned);
278 
279 /**
280  * snd_pcm_format_linear - Check the PCM format is linear
281  * @format: the format to check
282  *
283  * Return: 1 if the given PCM format is linear, 0 if not.
284  */
snd_pcm_format_linear(snd_pcm_format_t format)285 int snd_pcm_format_linear(snd_pcm_format_t format)
286 {
287 	return snd_pcm_format_signed(format) >= 0;
288 }
289 EXPORT_SYMBOL(snd_pcm_format_linear);
290 
291 /**
292  * snd_pcm_format_little_endian - Check the PCM format is little-endian
293  * @format: the format to check
294  *
295  * Return: 1 if the given PCM format is little-endian, 0 if
296  * big-endian, or a negative error code if endian not specified.
297  */
snd_pcm_format_little_endian(snd_pcm_format_t format)298 int snd_pcm_format_little_endian(snd_pcm_format_t format)
299 {
300 	int val;
301 	if (!valid_format(format))
302 		return -EINVAL;
303 	val = pcm_formats[(INT)format].le;
304 	if (val < 0)
305 		return -EINVAL;
306 	return val;
307 }
308 EXPORT_SYMBOL(snd_pcm_format_little_endian);
309 
310 /**
311  * snd_pcm_format_big_endian - Check the PCM format is big-endian
312  * @format: the format to check
313  *
314  * Return: 1 if the given PCM format is big-endian, 0 if
315  * little-endian, or a negative error code if endian not specified.
316  */
snd_pcm_format_big_endian(snd_pcm_format_t format)317 int snd_pcm_format_big_endian(snd_pcm_format_t format)
318 {
319 	int val;
320 
321 	val = snd_pcm_format_little_endian(format);
322 	if (val < 0)
323 		return val;
324 	return !val;
325 }
326 EXPORT_SYMBOL(snd_pcm_format_big_endian);
327 
328 /**
329  * snd_pcm_format_width - return the bit-width of the format
330  * @format: the format to check
331  *
332  * Return: The bit-width of the format, or a negative error code
333  * if unknown format.
334  */
snd_pcm_format_width(snd_pcm_format_t format)335 int snd_pcm_format_width(snd_pcm_format_t format)
336 {
337 	int val;
338 	if (!valid_format(format))
339 		return -EINVAL;
340 	val = pcm_formats[(INT)format].width;
341 	if (!val)
342 		return -EINVAL;
343 	return val;
344 }
345 EXPORT_SYMBOL(snd_pcm_format_width);
346 
347 /**
348  * snd_pcm_format_physical_width - return the physical bit-width of the format
349  * @format: the format to check
350  *
351  * Return: The physical bit-width of the format, or a negative error code
352  * if unknown format.
353  */
snd_pcm_format_physical_width(snd_pcm_format_t format)354 int snd_pcm_format_physical_width(snd_pcm_format_t format)
355 {
356 	int val;
357 	if (!valid_format(format))
358 		return -EINVAL;
359 	val = pcm_formats[(INT)format].phys;
360 	if (!val)
361 		return -EINVAL;
362 	return val;
363 }
364 EXPORT_SYMBOL(snd_pcm_format_physical_width);
365 
366 /**
367  * snd_pcm_format_size - return the byte size of samples on the given format
368  * @format: the format to check
369  * @samples: sampling rate
370  *
371  * Return: The byte size of the given samples for the format, or a
372  * negative error code if unknown format.
373  */
snd_pcm_format_size(snd_pcm_format_t format,size_t samples)374 ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples)
375 {
376 	int phys_width = snd_pcm_format_physical_width(format);
377 	if (phys_width < 0)
378 		return -EINVAL;
379 	return samples * phys_width / 8;
380 }
381 EXPORT_SYMBOL(snd_pcm_format_size);
382 
383 /**
384  * snd_pcm_format_silence_64 - return the silent data in 8 bytes array
385  * @format: the format to check
386  *
387  * Return: The format pattern to fill or %NULL if error.
388  */
snd_pcm_format_silence_64(snd_pcm_format_t format)389 const unsigned char *snd_pcm_format_silence_64(snd_pcm_format_t format)
390 {
391 	if (!valid_format(format))
392 		return NULL;
393 	if (! pcm_formats[(INT)format].phys)
394 		return NULL;
395 	return pcm_formats[(INT)format].silence;
396 }
397 EXPORT_SYMBOL(snd_pcm_format_silence_64);
398 
399 /**
400  * snd_pcm_format_set_silence - set the silence data on the buffer
401  * @format: the PCM format
402  * @data: the buffer pointer
403  * @samples: the number of samples to set silence
404  *
405  * Sets the silence data on the buffer for the given samples.
406  *
407  * Return: Zero if successful, or a negative error code on failure.
408  */
snd_pcm_format_set_silence(snd_pcm_format_t format,void * data,unsigned int samples)409 int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int samples)
410 {
411 	int width;
412 	unsigned char *dst;
413 	const unsigned char *pat;
414 
415 	if (!valid_format(format))
416 		return -EINVAL;
417 	if (samples == 0)
418 		return 0;
419 	width = pcm_formats[(INT)format].phys; /* physical width */
420 	if (!width)
421 		return -EINVAL;
422 	pat = pcm_formats[(INT)format].silence;
423 	/* signed or 1 byte data */
424 	if (pcm_formats[(INT)format].signd == 1 || width <= 8) {
425 		unsigned int bytes = samples * width / 8;
426 		memset(data, *pat, bytes);
427 		return 0;
428 	}
429 	/* non-zero samples, fill using a loop */
430 	width /= 8;
431 	dst = data;
432 #if 0
433 	while (samples--) {
434 		memcpy(dst, pat, width);
435 		dst += width;
436 	}
437 #else
438 	/* a bit optimization for constant width */
439 	switch (width) {
440 	case 2:
441 		while (samples--) {
442 			memcpy(dst, pat, 2);
443 			dst += 2;
444 		}
445 		break;
446 	case 3:
447 		while (samples--) {
448 			memcpy(dst, pat, 3);
449 			dst += 3;
450 		}
451 		break;
452 	case 4:
453 		while (samples--) {
454 			memcpy(dst, pat, 4);
455 			dst += 4;
456 		}
457 		break;
458 	case 8:
459 		while (samples--) {
460 			memcpy(dst, pat, 8);
461 			dst += 8;
462 		}
463 		break;
464 	}
465 #endif
466 	return 0;
467 }
468 EXPORT_SYMBOL(snd_pcm_format_set_silence);
469 
470 /**
471  * snd_pcm_hw_limit_rates - determine rate_min/rate_max fields
472  * @hw: the pcm hw instance
473  *
474  * Determines the rate_min and rate_max fields from the rates bits of
475  * the given hw.
476  *
477  * Return: Zero if successful.
478  */
snd_pcm_hw_limit_rates(struct snd_pcm_hardware * hw)479 int snd_pcm_hw_limit_rates(struct snd_pcm_hardware *hw)
480 {
481 	int i;
482 	unsigned int rmin, rmax;
483 
484 	rmin = UINT_MAX;
485 	rmax = 0;
486 	for (i = 0; i < (int)snd_pcm_known_rates.count; i++) {
487 		if (hw->rates & (1 << i)) {
488 			rmin = min(rmin, snd_pcm_known_rates.list[i]);
489 			rmax = max(rmax, snd_pcm_known_rates.list[i]);
490 		}
491 	}
492 	if (rmin > rmax)
493 		return -EINVAL;
494 	hw->rate_min = rmin;
495 	hw->rate_max = rmax;
496 	return 0;
497 }
498 EXPORT_SYMBOL(snd_pcm_hw_limit_rates);
499 
500 /**
501  * snd_pcm_rate_to_rate_bit - converts sample rate to SNDRV_PCM_RATE_xxx bit
502  * @rate: the sample rate to convert
503  *
504  * Return: The SNDRV_PCM_RATE_xxx flag that corresponds to the given rate, or
505  * SNDRV_PCM_RATE_KNOT for an unknown rate.
506  */
snd_pcm_rate_to_rate_bit(unsigned int rate)507 unsigned int snd_pcm_rate_to_rate_bit(unsigned int rate)
508 {
509 	unsigned int i;
510 
511 	for (i = 0; i < snd_pcm_known_rates.count; i++)
512 		if (snd_pcm_known_rates.list[i] == rate)
513 			return 1u << i;
514 	return SNDRV_PCM_RATE_KNOT;
515 }
516 EXPORT_SYMBOL(snd_pcm_rate_to_rate_bit);
517 
518 /**
519  * snd_pcm_rate_bit_to_rate - converts SNDRV_PCM_RATE_xxx bit to sample rate
520  * @rate_bit: the rate bit to convert
521  *
522  * Return: The sample rate that corresponds to the given SNDRV_PCM_RATE_xxx flag
523  * or 0 for an unknown rate bit.
524  */
snd_pcm_rate_bit_to_rate(unsigned int rate_bit)525 unsigned int snd_pcm_rate_bit_to_rate(unsigned int rate_bit)
526 {
527 	unsigned int i;
528 
529 	for (i = 0; i < snd_pcm_known_rates.count; i++)
530 		if ((1u << i) == rate_bit)
531 			return snd_pcm_known_rates.list[i];
532 	return 0;
533 }
534 EXPORT_SYMBOL(snd_pcm_rate_bit_to_rate);
535 
snd_pcm_rate_mask_sanitize(unsigned int rates)536 static unsigned int snd_pcm_rate_mask_sanitize(unsigned int rates)
537 {
538 	if (rates & SNDRV_PCM_RATE_CONTINUOUS)
539 		return SNDRV_PCM_RATE_CONTINUOUS;
540 	else if (rates & SNDRV_PCM_RATE_KNOT)
541 		return SNDRV_PCM_RATE_KNOT;
542 	return rates;
543 }
544 
545 /**
546  * snd_pcm_rate_mask_intersect - computes the intersection between two rate masks
547  * @rates_a: The first rate mask
548  * @rates_b: The second rate mask
549  *
550  * This function computes the rates that are supported by both rate masks passed
551  * to the function. It will take care of the special handling of
552  * SNDRV_PCM_RATE_CONTINUOUS and SNDRV_PCM_RATE_KNOT.
553  *
554  * Return: A rate mask containing the rates that are supported by both rates_a
555  * and rates_b.
556  */
snd_pcm_rate_mask_intersect(unsigned int rates_a,unsigned int rates_b)557 unsigned int snd_pcm_rate_mask_intersect(unsigned int rates_a,
558 	unsigned int rates_b)
559 {
560 	rates_a = snd_pcm_rate_mask_sanitize(rates_a);
561 	rates_b = snd_pcm_rate_mask_sanitize(rates_b);
562 
563 	if (rates_a & SNDRV_PCM_RATE_CONTINUOUS)
564 		return rates_b;
565 	else if (rates_b & SNDRV_PCM_RATE_CONTINUOUS)
566 		return rates_a;
567 	else if (rates_a & SNDRV_PCM_RATE_KNOT)
568 		return rates_b;
569 	else if (rates_b & SNDRV_PCM_RATE_KNOT)
570 		return rates_a;
571 	return rates_a & rates_b;
572 }
573 EXPORT_SYMBOL_GPL(snd_pcm_rate_mask_intersect);
574