1 /***
2 This file is part of PulseAudio.
3
4 Copyright 2004-2006 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
6
7 PulseAudio is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published
9 by the Free Software Foundation; either version 2.1 of the License,
10 or (at your option) any later version.
11
12 PulseAudio is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
19 ***/
20
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24
25 #include <stdio.h>
26 #include <string.h>
27
28 #include <pulse/timeval.h>
29
30 #include <pulsecore/core-util.h>
31 #include <pulsecore/i18n.h>
32 #include <pulsecore/macro.h>
33
34 #include "sample.h"
35
36 static const size_t size_table[] = {
37 [PA_SAMPLE_U8] = 1,
38 [PA_SAMPLE_ULAW] = 1,
39 [PA_SAMPLE_ALAW] = 1,
40 [PA_SAMPLE_S16LE] = 2,
41 [PA_SAMPLE_S16BE] = 2,
42 [PA_SAMPLE_FLOAT32LE] = 4,
43 [PA_SAMPLE_FLOAT32BE] = 4,
44 [PA_SAMPLE_S32LE] = 4,
45 [PA_SAMPLE_S32BE] = 4,
46 [PA_SAMPLE_S24LE] = 3,
47 [PA_SAMPLE_S24BE] = 3,
48 [PA_SAMPLE_S24_32LE] = 4,
49 [PA_SAMPLE_S24_32BE] = 4
50 };
51
pa_sample_size_of_format(pa_sample_format_t f)52 size_t pa_sample_size_of_format(pa_sample_format_t f) {
53 pa_assert(pa_sample_format_valid(f));
54
55 return size_table[f];
56 }
57
pa_sample_size(const pa_sample_spec * spec)58 size_t pa_sample_size(const pa_sample_spec *spec) {
59 pa_assert(spec);
60 pa_assert(pa_sample_spec_valid(spec));
61
62 return size_table[spec->format];
63 }
64
pa_frame_size(const pa_sample_spec * spec)65 size_t pa_frame_size(const pa_sample_spec *spec) {
66 pa_assert(spec);
67 pa_assert(pa_sample_spec_valid(spec));
68
69 return size_table[spec->format] * spec->channels;
70 }
71
pa_bytes_per_second(const pa_sample_spec * spec)72 size_t pa_bytes_per_second(const pa_sample_spec *spec) {
73 pa_assert(spec);
74 pa_assert(pa_sample_spec_valid(spec));
75
76 return spec->rate * size_table[spec->format] * spec->channels;
77 }
78
pa_bytes_to_usec(uint64_t length,const pa_sample_spec * spec)79 pa_usec_t pa_bytes_to_usec(uint64_t length, const pa_sample_spec *spec) {
80 pa_assert(spec);
81 pa_assert(pa_sample_spec_valid(spec));
82
83 return (((pa_usec_t) (length / (size_table[spec->format] * spec->channels)) * PA_USEC_PER_SEC) / spec->rate);
84 }
85
pa_usec_to_bytes(pa_usec_t t,const pa_sample_spec * spec)86 size_t pa_usec_to_bytes(pa_usec_t t, const pa_sample_spec *spec) {
87 pa_assert(spec);
88 pa_assert(pa_sample_spec_valid(spec));
89
90 return (size_t) (((t * spec->rate) / PA_USEC_PER_SEC)) * (size_table[spec->format] * spec->channels);
91 }
92
pa_sample_spec_init(pa_sample_spec * spec)93 pa_sample_spec* pa_sample_spec_init(pa_sample_spec *spec) {
94 pa_assert(spec);
95
96 spec->format = PA_SAMPLE_INVALID;
97 spec->rate = 0;
98 spec->channels = 0;
99
100 return spec;
101 }
102
pa_sample_format_valid(unsigned format)103 int pa_sample_format_valid(unsigned format) {
104 return format < PA_SAMPLE_MAX;
105 }
106
pa_sample_rate_valid(uint32_t rate)107 int pa_sample_rate_valid(uint32_t rate) {
108 /* The extra 1% is due to module-loopback: it temporarily sets
109 * a higher-than-nominal rate to get rid of excessive buffer
110 * latency */
111 return rate > 0 && rate <= PA_RATE_MAX * 101 / 100;
112 }
113
pa_channels_valid(uint8_t channels)114 int pa_channels_valid(uint8_t channels) {
115 return channels > 0 && channels <= PA_CHANNELS_MAX;
116 }
117
pa_sample_spec_valid(const pa_sample_spec * spec)118 int pa_sample_spec_valid(const pa_sample_spec *spec) {
119 pa_assert(spec);
120
121 if (PA_UNLIKELY(!pa_sample_rate_valid(spec->rate) ||
122 !pa_channels_valid(spec->channels) ||
123 !pa_sample_format_valid(spec->format)))
124 return 0;
125
126 return 1;
127 }
128
pa_sample_spec_equal(const pa_sample_spec * a,const pa_sample_spec * b)129 int pa_sample_spec_equal(const pa_sample_spec*a, const pa_sample_spec*b) {
130 pa_assert(a);
131 pa_assert(b);
132
133 pa_return_val_if_fail(pa_sample_spec_valid(a), 0);
134
135 if (PA_UNLIKELY(a == b))
136 return 1;
137
138 pa_return_val_if_fail(pa_sample_spec_valid(b), 0);
139
140 return
141 (a->format == b->format) &&
142 (a->rate == b->rate) &&
143 (a->channels == b->channels);
144 }
145
pa_sample_format_to_string(pa_sample_format_t f)146 const char *pa_sample_format_to_string(pa_sample_format_t f) {
147 static const char* const table[]= {
148 [PA_SAMPLE_U8] = "u8",
149 [PA_SAMPLE_ALAW] = "aLaw",
150 [PA_SAMPLE_ULAW] = "uLaw",
151 [PA_SAMPLE_S16LE] = "s16le",
152 [PA_SAMPLE_S16BE] = "s16be",
153 [PA_SAMPLE_FLOAT32LE] = "float32le",
154 [PA_SAMPLE_FLOAT32BE] = "float32be",
155 [PA_SAMPLE_S32LE] = "s32le",
156 [PA_SAMPLE_S32BE] = "s32be",
157 [PA_SAMPLE_S24LE] = "s24le",
158 [PA_SAMPLE_S24BE] = "s24be",
159 [PA_SAMPLE_S24_32LE] = "s24-32le",
160 [PA_SAMPLE_S24_32BE] = "s24-32be",
161 };
162
163 if (!pa_sample_format_valid(f))
164 return NULL;
165
166 return table[f];
167 }
168
pa_sample_spec_snprint(char * s,size_t l,const pa_sample_spec * spec)169 char *pa_sample_spec_snprint(char *s, size_t l, const pa_sample_spec *spec) {
170 pa_assert(s);
171 pa_assert(l > 0);
172 pa_assert(spec);
173
174 pa_init_i18n();
175
176 if (!pa_sample_spec_valid(spec))
177 pa_snprintf(s, l, _("(invalid)"));
178 else
179 pa_snprintf(s, l, _("%s %uch %uHz"), pa_sample_format_to_string(spec->format), spec->channels, spec->rate);
180
181 return s;
182 }
183
pa_bytes_snprint(char * s,size_t l,unsigned v)184 char* pa_bytes_snprint(char *s, size_t l, unsigned v) {
185 pa_assert(s);
186 pa_assert(l > 0);
187
188 pa_init_i18n();
189
190 if (v >= ((unsigned) 1024)*1024*1024)
191 pa_snprintf(s, l, _("%0.1f GiB"), ((double) v)/1024/1024/1024);
192 else if (v >= ((unsigned) 1024)*1024)
193 pa_snprintf(s, l, _("%0.1f MiB"), ((double) v)/1024/1024);
194 else if (v >= (unsigned) 1024)
195 pa_snprintf(s, l, _("%0.1f KiB"), ((double) v)/1024);
196 else
197 pa_snprintf(s, l, _("%u B"), (unsigned) v);
198
199 return s;
200 }
201
pa_parse_sample_format(const char * format)202 pa_sample_format_t pa_parse_sample_format(const char *format) {
203 pa_assert(format);
204
205 if (strcasecmp(format, "s16le") == 0)
206 return PA_SAMPLE_S16LE;
207 else if (strcasecmp(format, "s16be") == 0)
208 return PA_SAMPLE_S16BE;
209 else if (strcasecmp(format, "s16ne") == 0 || strcasecmp(format, "s16") == 0 || strcasecmp(format, "16") == 0)
210 return PA_SAMPLE_S16NE;
211 else if (strcasecmp(format, "s16re") == 0)
212 return PA_SAMPLE_S16RE;
213 else if (strcasecmp(format, "u8") == 0 || strcasecmp(format, "8") == 0)
214 return PA_SAMPLE_U8;
215 else if (strcasecmp(format, "float32") == 0 || strcasecmp(format, "float32ne") == 0 || strcasecmp(format, "float") == 0)
216 return PA_SAMPLE_FLOAT32NE;
217 else if (strcasecmp(format, "float32re") == 0)
218 return PA_SAMPLE_FLOAT32RE;
219 else if (strcasecmp(format, "float32le") == 0)
220 return PA_SAMPLE_FLOAT32LE;
221 else if (strcasecmp(format, "float32be") == 0)
222 return PA_SAMPLE_FLOAT32BE;
223 else if (strcasecmp(format, "ulaw") == 0 || strcasecmp(format, "mulaw") == 0)
224 return PA_SAMPLE_ULAW;
225 else if (strcasecmp(format, "alaw") == 0)
226 return PA_SAMPLE_ALAW;
227 else if (strcasecmp(format, "s32le") == 0)
228 return PA_SAMPLE_S32LE;
229 else if (strcasecmp(format, "s32be") == 0)
230 return PA_SAMPLE_S32BE;
231 else if (strcasecmp(format, "s32ne") == 0 || strcasecmp(format, "s32") == 0 || strcasecmp(format, "32") == 0)
232 return PA_SAMPLE_S32NE;
233 else if (strcasecmp(format, "s32re") == 0)
234 return PA_SAMPLE_S24RE;
235 else if (strcasecmp(format, "s24le") == 0)
236 return PA_SAMPLE_S24LE;
237 else if (strcasecmp(format, "s24be") == 0)
238 return PA_SAMPLE_S24BE;
239 else if (strcasecmp(format, "s24ne") == 0 || strcasecmp(format, "s24") == 0 || strcasecmp(format, "24") == 0)
240 return PA_SAMPLE_S24NE;
241 else if (strcasecmp(format, "s24re") == 0)
242 return PA_SAMPLE_S24RE;
243 else if (strcasecmp(format, "s24-32le") == 0)
244 return PA_SAMPLE_S24_32LE;
245 else if (strcasecmp(format, "s24-32be") == 0)
246 return PA_SAMPLE_S24_32BE;
247 else if (strcasecmp(format, "s24-32ne") == 0 || strcasecmp(format, "s24-32") == 0)
248 return PA_SAMPLE_S24_32NE;
249 else if (strcasecmp(format, "s24-32re") == 0)
250 return PA_SAMPLE_S24_32RE;
251
252 return PA_SAMPLE_INVALID;
253 }
254
pa_sample_format_is_le(pa_sample_format_t f)255 int pa_sample_format_is_le(pa_sample_format_t f) {
256 pa_assert(pa_sample_format_valid(f));
257
258 switch (f) {
259 case PA_SAMPLE_S16LE:
260 case PA_SAMPLE_S24LE:
261 case PA_SAMPLE_S32LE:
262 case PA_SAMPLE_S24_32LE:
263 case PA_SAMPLE_FLOAT32LE:
264 return 1;
265
266 case PA_SAMPLE_S16BE:
267 case PA_SAMPLE_S24BE:
268 case PA_SAMPLE_S32BE:
269 case PA_SAMPLE_S24_32BE:
270 case PA_SAMPLE_FLOAT32BE:
271 return 0;
272
273 default:
274 return -1;
275 }
276 }
277
pa_sample_format_is_be(pa_sample_format_t f)278 int pa_sample_format_is_be(pa_sample_format_t f) {
279 int r;
280
281 if ((r = pa_sample_format_is_le(f)) < 0)
282 return r;
283
284 return !r;
285 }
286