Branch data Line data Source code
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, write to the Free Software
19 : : Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 : : USA.
21 : : ***/
22 : :
23 : : #ifdef HAVE_CONFIG_H
24 : : #include <config.h>
25 : : #endif
26 : :
27 : : #include <stdio.h>
28 : : #include <string.h>
29 : :
30 : : #include <pulse/timeval.h>
31 : :
32 : : #include <pulsecore/core-util.h>
33 : : #include <pulsecore/i18n.h>
34 : : #include <pulsecore/macro.h>
35 : :
36 : : #include "sample.h"
37 : :
38 : : static const size_t size_table[] = {
39 : : [PA_SAMPLE_U8] = 1,
40 : : [PA_SAMPLE_ULAW] = 1,
41 : : [PA_SAMPLE_ALAW] = 1,
42 : : [PA_SAMPLE_S16LE] = 2,
43 : : [PA_SAMPLE_S16BE] = 2,
44 : : [PA_SAMPLE_FLOAT32LE] = 4,
45 : : [PA_SAMPLE_FLOAT32BE] = 4,
46 : : [PA_SAMPLE_S32LE] = 4,
47 : : [PA_SAMPLE_S32BE] = 4,
48 : : [PA_SAMPLE_S24LE] = 3,
49 : : [PA_SAMPLE_S24BE] = 3,
50 : : [PA_SAMPLE_S24_32LE] = 4,
51 : : [PA_SAMPLE_S24_32BE] = 4
52 : : };
53 : :
54 : 338 : size_t pa_sample_size_of_format(pa_sample_format_t f) {
55 [ - + ]: 338 : pa_assert(f >= 0);
56 [ - + ]: 338 : pa_assert(f < PA_SAMPLE_MAX);
57 : :
58 : 338 : return size_table[f];
59 : : }
60 : :
61 : 0 : size_t pa_sample_size(const pa_sample_spec *spec) {
62 : :
63 [ # # ]: 0 : pa_assert(spec);
64 [ # # ]: 0 : pa_return_val_if_fail(pa_sample_spec_valid(spec), 0);
65 : :
66 : 0 : return size_table[spec->format];
67 : : }
68 : :
69 : 872 : size_t pa_frame_size(const pa_sample_spec *spec) {
70 [ - + ]: 872 : pa_assert(spec);
71 [ - + ]: 872 : pa_return_val_if_fail(pa_sample_spec_valid(spec), 0);
72 : :
73 : 872 : return size_table[spec->format] * spec->channels;
74 : : }
75 : :
76 : 0 : size_t pa_bytes_per_second(const pa_sample_spec *spec) {
77 [ # # ]: 0 : pa_assert(spec);
78 [ # # ]: 0 : pa_return_val_if_fail(pa_sample_spec_valid(spec), 0);
79 : :
80 : 0 : return spec->rate * size_table[spec->format] * spec->channels;
81 : : }
82 : :
83 : 0 : pa_usec_t pa_bytes_to_usec(uint64_t length, const pa_sample_spec *spec) {
84 [ # # ]: 0 : pa_assert(spec);
85 [ # # ]: 0 : pa_return_val_if_fail(pa_sample_spec_valid(spec), 0);
86 : :
87 : 0 : return (((pa_usec_t) (length / (size_table[spec->format] * spec->channels)) * PA_USEC_PER_SEC) / spec->rate);
88 : : }
89 : :
90 : 0 : size_t pa_usec_to_bytes(pa_usec_t t, const pa_sample_spec *spec) {
91 [ # # ]: 0 : pa_assert(spec);
92 [ # # ]: 0 : pa_return_val_if_fail(pa_sample_spec_valid(spec), 0);
93 : :
94 : 0 : return (size_t) (((t * spec->rate) / PA_USEC_PER_SEC)) * (size_table[spec->format] * spec->channels);
95 : : }
96 : :
97 : 0 : pa_sample_spec* pa_sample_spec_init(pa_sample_spec *spec) {
98 [ # # ]: 0 : pa_assert(spec);
99 : :
100 : 0 : spec->format = PA_SAMPLE_INVALID;
101 : 0 : spec->rate = 0;
102 : 0 : spec->channels = 0;
103 : :
104 : 0 : return spec;
105 : : }
106 : :
107 : 1561 : int pa_sample_spec_valid(const pa_sample_spec *spec) {
108 [ - + ]: 1561 : pa_assert(spec);
109 : :
110 [ + - ][ + - ]: 1561 : if (PA_UNLIKELY (spec->rate <= 0 ||
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
111 : : spec->rate > PA_RATE_MAX ||
112 : : spec->channels <= 0 ||
113 : : spec->channels > PA_CHANNELS_MAX ||
114 : : spec->format >= PA_SAMPLE_MAX ||
115 : : spec->format < 0))
116 : : return 0;
117 : :
118 : 1561 : return 1;
119 : : }
120 : :
121 : 0 : int pa_sample_spec_equal(const pa_sample_spec*a, const pa_sample_spec*b) {
122 [ # # ]: 0 : pa_assert(a);
123 [ # # ]: 0 : pa_assert(b);
124 : :
125 [ # # ]: 0 : pa_return_val_if_fail(pa_sample_spec_valid(a), 0);
126 : :
127 [ # # ]: 0 : if (PA_UNLIKELY(a == b))
128 : : return 1;
129 : :
130 [ # # ]: 0 : pa_return_val_if_fail(pa_sample_spec_valid(b), 0);
131 : :
132 [ # # ]: 0 : return
133 [ # # ]: 0 : (a->format == b->format) &&
134 [ # # ]: 0 : (a->rate == b->rate) &&
135 : 0 : (a->channels == b->channels);
136 : : }
137 : :
138 : 858 : const char *pa_sample_format_to_string(pa_sample_format_t f) {
139 : : static const char* const table[]= {
140 : : [PA_SAMPLE_U8] = "u8",
141 : : [PA_SAMPLE_ALAW] = "aLaw",
142 : : [PA_SAMPLE_ULAW] = "uLaw",
143 : : [PA_SAMPLE_S16LE] = "s16le",
144 : : [PA_SAMPLE_S16BE] = "s16be",
145 : : [PA_SAMPLE_FLOAT32LE] = "float32le",
146 : : [PA_SAMPLE_FLOAT32BE] = "float32be",
147 : : [PA_SAMPLE_S32LE] = "s32le",
148 : : [PA_SAMPLE_S32BE] = "s32be",
149 : : [PA_SAMPLE_S24LE] = "s24le",
150 : : [PA_SAMPLE_S24BE] = "s24be",
151 : : [PA_SAMPLE_S24_32LE] = "s24-32le",
152 : : [PA_SAMPLE_S24_32BE] = "s24-32be",
153 : : };
154 : :
155 [ + - ]: 858 : if (f < 0 || f >= PA_SAMPLE_MAX)
156 : : return NULL;
157 : :
158 : 858 : return table[f];
159 : : }
160 : :
161 : 0 : char *pa_sample_spec_snprint(char *s, size_t l, const pa_sample_spec *spec) {
162 [ # # ]: 0 : pa_assert(s);
163 [ # # ]: 0 : pa_assert(l > 0);
164 [ # # ]: 0 : pa_assert(spec);
165 : :
166 : 0 : pa_init_i18n();
167 : :
168 [ # # ]: 0 : if (!pa_sample_spec_valid(spec))
169 : 0 : pa_snprintf(s, l, _("(invalid)"));
170 : : else
171 : 0 : pa_snprintf(s, l, _("%s %uch %uHz"), pa_sample_format_to_string(spec->format), spec->channels, spec->rate);
172 : :
173 : 0 : return s;
174 : : }
175 : :
176 : 14 : char* pa_bytes_snprint(char *s, size_t l, unsigned v) {
177 [ - + ]: 14 : pa_assert(s);
178 [ - + ]: 14 : pa_assert(l > 0);
179 : :
180 : 14 : pa_init_i18n();
181 : :
182 [ - + ]: 14 : if (v >= ((unsigned) 1024)*1024*1024)
183 : 0 : pa_snprintf(s, l, _("%0.1f GiB"), ((double) v)/1024/1024/1024);
184 [ + + ]: 14 : else if (v >= ((unsigned) 1024)*1024)
185 : 7 : pa_snprintf(s, l, _("%0.1f MiB"), ((double) v)/1024/1024);
186 [ + - ]: 7 : else if (v >= (unsigned) 1024)
187 : 7 : pa_snprintf(s, l, _("%0.1f KiB"), ((double) v)/1024);
188 : : else
189 : 0 : pa_snprintf(s, l, _("%u B"), (unsigned) v);
190 : :
191 : 14 : return s;
192 : : }
193 : :
194 : 0 : pa_sample_format_t pa_parse_sample_format(const char *format) {
195 [ # # ]: 0 : pa_assert(format);
196 : :
197 [ # # ]: 0 : if (strcasecmp(format, "s16le") == 0)
198 : : return PA_SAMPLE_S16LE;
199 [ # # ]: 0 : else if (strcasecmp(format, "s16be") == 0)
200 : : return PA_SAMPLE_S16BE;
201 [ # # ][ # # ]: 0 : else if (strcasecmp(format, "s16ne") == 0 || strcasecmp(format, "s16") == 0 || strcasecmp(format, "16") == 0)
[ # # ]
202 : : return PA_SAMPLE_S16NE;
203 [ # # ]: 0 : else if (strcasecmp(format, "s16re") == 0)
204 : : return PA_SAMPLE_S16RE;
205 [ # # ][ # # ]: 0 : else if (strcasecmp(format, "u8") == 0 || strcasecmp(format, "8") == 0)
206 : : return PA_SAMPLE_U8;
207 [ # # ][ # # ]: 0 : else if (strcasecmp(format, "float32") == 0 || strcasecmp(format, "float32ne") == 0 || strcasecmp(format, "float") == 0)
[ # # ]
208 : : return PA_SAMPLE_FLOAT32NE;
209 [ # # ]: 0 : else if (strcasecmp(format, "float32re") == 0)
210 : : return PA_SAMPLE_FLOAT32RE;
211 [ # # ]: 0 : else if (strcasecmp(format, "float32le") == 0)
212 : : return PA_SAMPLE_FLOAT32LE;
213 [ # # ]: 0 : else if (strcasecmp(format, "float32be") == 0)
214 : : return PA_SAMPLE_FLOAT32BE;
215 [ # # ][ # # ]: 0 : else if (strcasecmp(format, "ulaw") == 0 || strcasecmp(format, "mulaw") == 0)
216 : : return PA_SAMPLE_ULAW;
217 [ # # ]: 0 : else if (strcasecmp(format, "alaw") == 0)
218 : : return PA_SAMPLE_ALAW;
219 [ # # ]: 0 : else if (strcasecmp(format, "s32le") == 0)
220 : : return PA_SAMPLE_S32LE;
221 [ # # ]: 0 : else if (strcasecmp(format, "s32be") == 0)
222 : : return PA_SAMPLE_S32BE;
223 [ # # ][ # # ]: 0 : else if (strcasecmp(format, "s32ne") == 0 || strcasecmp(format, "s32") == 0 || strcasecmp(format, "32") == 0)
[ # # ]
224 : : return PA_SAMPLE_S32NE;
225 [ # # ]: 0 : else if (strcasecmp(format, "s32re") == 0)
226 : : return PA_SAMPLE_S24RE;
227 [ # # ]: 0 : else if (strcasecmp(format, "s24le") == 0)
228 : : return PA_SAMPLE_S24LE;
229 [ # # ]: 0 : else if (strcasecmp(format, "s24be") == 0)
230 : : return PA_SAMPLE_S24BE;
231 [ # # ][ # # ]: 0 : else if (strcasecmp(format, "s24ne") == 0 || strcasecmp(format, "s24") == 0 || strcasecmp(format, "24") == 0)
[ # # ]
232 : : return PA_SAMPLE_S24NE;
233 [ # # ]: 0 : else if (strcasecmp(format, "s24re") == 0)
234 : : return PA_SAMPLE_S24RE;
235 [ # # ]: 0 : else if (strcasecmp(format, "s24-32le") == 0)
236 : : return PA_SAMPLE_S24_32LE;
237 [ # # ]: 0 : else if (strcasecmp(format, "s24-32be") == 0)
238 : : return PA_SAMPLE_S24_32BE;
239 [ # # ][ # # ]: 0 : else if (strcasecmp(format, "s24-32ne") == 0 || strcasecmp(format, "s24-32") == 0)
240 : : return PA_SAMPLE_S24_32NE;
241 [ # # ]: 0 : else if (strcasecmp(format, "s24-32re") == 0)
242 : : return PA_SAMPLE_S24_32RE;
243 : :
244 : 0 : return PA_SAMPLE_INVALID;
245 : : }
246 : :
247 : 0 : int pa_sample_format_is_le(pa_sample_format_t f) {
248 [ # # ]: 0 : pa_assert(f >= PA_SAMPLE_U8);
249 [ # # ]: 0 : pa_assert(f < PA_SAMPLE_MAX);
250 : :
251 [ # # # ]: 0 : switch (f) {
252 : : case PA_SAMPLE_S16LE:
253 : : case PA_SAMPLE_S24LE:
254 : : case PA_SAMPLE_S32LE:
255 : : case PA_SAMPLE_S24_32LE:
256 : : case PA_SAMPLE_FLOAT32LE:
257 : : return 1;
258 : :
259 : : case PA_SAMPLE_S16BE:
260 : : case PA_SAMPLE_S24BE:
261 : : case PA_SAMPLE_S32BE:
262 : : case PA_SAMPLE_S24_32BE:
263 : : case PA_SAMPLE_FLOAT32BE:
264 : 0 : return 0;
265 : :
266 : : default:
267 : 0 : return -1;
268 : : }
269 : : }
270 : :
271 : 0 : int pa_sample_format_is_be(pa_sample_format_t f) {
272 : : int r;
273 : :
274 [ # # ]: 0 : if ((r = pa_sample_format_is_le(f)) < 0)
275 : : return r;
276 : :
277 : 0 : return !r;
278 : : }
|