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