• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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