2 This file is part of PulseAudio.
4 Copyright 2004-2006 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
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.
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.
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
30 #include <pulse/timeval.h>
31 #include <pulse/i18n.h>
33 #include <pulsecore/core-util.h>
34 #include <pulsecore/macro.h>
38 static const size_t size_table
[] = {
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
54 size_t pa_sample_size_of_format(pa_sample_format_t f
) {
56 pa_assert(f
< PA_SAMPLE_MAX
);
61 size_t pa_sample_size(const pa_sample_spec
*spec
) {
64 pa_return_val_if_fail(pa_sample_spec_valid(spec
), 0);
66 return size_table
[spec
->format
];
69 size_t pa_frame_size(const pa_sample_spec
*spec
) {
71 pa_return_val_if_fail(pa_sample_spec_valid(spec
), 0);
73 return size_table
[spec
->format
] * spec
->channels
;
76 size_t pa_bytes_per_second(const pa_sample_spec
*spec
) {
78 pa_return_val_if_fail(pa_sample_spec_valid(spec
), 0);
80 return spec
->rate
* size_table
[spec
->format
] * spec
->channels
;
83 pa_usec_t
pa_bytes_to_usec(uint64_t length
, const pa_sample_spec
*spec
) {
85 pa_return_val_if_fail(pa_sample_spec_valid(spec
), 0);
87 return (((pa_usec_t
) (length
/ (size_table
[spec
->format
] * spec
->channels
)) * PA_USEC_PER_SEC
) / spec
->rate
);
90 size_t pa_usec_to_bytes(pa_usec_t t
, const pa_sample_spec
*spec
) {
92 pa_return_val_if_fail(pa_sample_spec_valid(spec
), 0);
94 return (size_t) (((t
* spec
->rate
) / PA_USEC_PER_SEC
)) * (size_table
[spec
->format
] * spec
->channels
);
97 pa_sample_spec
* pa_sample_spec_init(pa_sample_spec
*spec
) {
100 spec
->format
= PA_SAMPLE_INVALID
;
107 int pa_sample_spec_valid(const pa_sample_spec
*spec
) {
110 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
||
121 int pa_sample_spec_equal(const pa_sample_spec
*a
, const pa_sample_spec
*b
) {
125 pa_return_val_if_fail(pa_sample_spec_valid(a
), 0);
127 if (PA_UNLIKELY(a
== b
))
130 pa_return_val_if_fail(pa_sample_spec_valid(b
), 0);
133 (a
->format
== b
->format
) &&
134 (a
->rate
== b
->rate
) &&
135 (a
->channels
== b
->channels
);
138 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",
155 if (f
< 0 || f
>= PA_SAMPLE_MAX
)
161 char *pa_sample_spec_snprint(char *s
, size_t l
, const pa_sample_spec
*spec
) {
168 if (!pa_sample_spec_valid(spec
))
169 pa_snprintf(s
, l
, _("(invalid)"));
171 pa_snprintf(s
, l
, _("%s %uch %uHz"), pa_sample_format_to_string(spec
->format
), spec
->channels
, spec
->rate
);
176 char* pa_bytes_snprint(char *s
, size_t l
, unsigned v
) {
182 if (v
>= ((unsigned) 1024)*1024*1024)
183 pa_snprintf(s
, l
, _("%0.1f GiB"), ((double) v
)/1024/1024/1024);
184 else if (v
>= ((unsigned) 1024)*1024)
185 pa_snprintf(s
, l
, _("%0.1f MiB"), ((double) v
)/1024/1024);
186 else if (v
>= (unsigned) 1024)
187 pa_snprintf(s
, l
, _("%0.1f KiB"), ((double) v
)/1024);
189 pa_snprintf(s
, l
, _("%u B"), (unsigned) v
);
194 pa_sample_format_t
pa_parse_sample_format(const char *format
) {
197 if (strcasecmp(format
, "s16le") == 0)
198 return PA_SAMPLE_S16LE
;
199 else if (strcasecmp(format
, "s16be") == 0)
200 return PA_SAMPLE_S16BE
;
201 else if (strcasecmp(format
, "s16ne") == 0 || strcasecmp(format
, "s16") == 0 || strcasecmp(format
, "16") == 0)
202 return PA_SAMPLE_S16NE
;
203 else if (strcasecmp(format
, "s16re") == 0)
204 return PA_SAMPLE_S16RE
;
205 else if (strcasecmp(format
, "u8") == 0 || strcasecmp(format
, "8") == 0)
207 else if (strcasecmp(format
, "float32") == 0 || strcasecmp(format
, "float32ne") == 0 || strcasecmp(format
, "float") == 0)
208 return PA_SAMPLE_FLOAT32NE
;
209 else if (strcasecmp(format
, "float32re") == 0)
210 return PA_SAMPLE_FLOAT32RE
;
211 else if (strcasecmp(format
, "float32le") == 0)
212 return PA_SAMPLE_FLOAT32LE
;
213 else if (strcasecmp(format
, "float32be") == 0)
214 return PA_SAMPLE_FLOAT32BE
;
215 else if (strcasecmp(format
, "ulaw") == 0 || strcasecmp(format
, "mulaw") == 0)
216 return PA_SAMPLE_ULAW
;
217 else if (strcasecmp(format
, "alaw") == 0)
218 return PA_SAMPLE_ALAW
;
219 else if (strcasecmp(format
, "s32le") == 0)
220 return PA_SAMPLE_S32LE
;
221 else if (strcasecmp(format
, "s32be") == 0)
222 return PA_SAMPLE_S32BE
;
223 else if (strcasecmp(format
, "s32ne") == 0 || strcasecmp(format
, "s32") == 0 || strcasecmp(format
, "32") == 0)
224 return PA_SAMPLE_S32NE
;
225 else if (strcasecmp(format
, "s32re") == 0)
226 return PA_SAMPLE_S24RE
;
227 else if (strcasecmp(format
, "s24le") == 0)
228 return PA_SAMPLE_S24LE
;
229 else if (strcasecmp(format
, "s24be") == 0)
230 return PA_SAMPLE_S24BE
;
231 else if (strcasecmp(format
, "s24ne") == 0 || strcasecmp(format
, "s24") == 0 || strcasecmp(format
, "24") == 0)
232 return PA_SAMPLE_S24NE
;
233 else if (strcasecmp(format
, "s24re") == 0)
234 return PA_SAMPLE_S24RE
;
235 else if (strcasecmp(format
, "s24-32le") == 0)
236 return PA_SAMPLE_S24_32LE
;
237 else if (strcasecmp(format
, "s24-32be") == 0)
238 return PA_SAMPLE_S24_32BE
;
239 else if (strcasecmp(format
, "s24-32ne") == 0 || strcasecmp(format
, "s24-32") == 0)
240 return PA_SAMPLE_S24_32NE
;
241 else if (strcasecmp(format
, "s24-32re") == 0)
242 return PA_SAMPLE_S24_32RE
;
244 return PA_SAMPLE_INVALID
;
247 int pa_sample_format_is_le(pa_sample_format_t f
) {
248 pa_assert(f
>= PA_SAMPLE_U8
);
249 pa_assert(f
< PA_SAMPLE_MAX
);
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
:
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
:
271 int pa_sample_format_is_be(pa_sample_format_t f
) {
274 if ((r
= pa_sample_format_is_le(f
)) < 0)