Branch data Line data Source code
1 : : /***
2 : : This file is part of PulseAudio.
3 : :
4 : : Copyright 2009 Lennart Poettering
5 : :
6 : : PulseAudio is free software; you can redistribute it and/or modify
7 : : it under the terms of the GNU Lesser General Public License as published
8 : : by the Free Software Foundation; either version 2.1 of the License,
9 : : or (at your option) any later version.
10 : :
11 : : PulseAudio is distributed in the hope that it will be useful, but
12 : : WITHOUT ANY WARRANTY; without even the implied warranty of
13 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : : General Public License for more details.
15 : :
16 : : You should have received a copy of the GNU Lesser General Public License
17 : : along with PulseAudio; if not, write to the Free Software
18 : : Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 : : USA.
20 : : ***/
21 : :
22 : : #ifdef HAVE_CONFIG_H
23 : : #include <config.h>
24 : : #endif
25 : :
26 : : /* Shared between pacat/parec/paplay and the server */
27 : :
28 : : #include <pulse/xmalloc.h>
29 : : #include <pulse/utf8.h>
30 : :
31 : : #include <pulsecore/macro.h>
32 : :
33 : : #include "sndfile-util.h"
34 : :
35 : 0 : int pa_sndfile_read_sample_spec(SNDFILE *sf, pa_sample_spec *ss) {
36 : : SF_INFO sfi;
37 : : int sf_errno;
38 : :
39 [ # # ]: 0 : pa_assert(sf);
40 [ # # ]: 0 : pa_assert(ss);
41 : :
42 : : pa_zero(sfi);
43 [ # # ]: 0 : if ((sf_errno = sf_command(sf, SFC_GET_CURRENT_SF_INFO, &sfi, sizeof(sfi)))) {
44 : 0 : pa_log_error("sndfile: %s", sf_error_number(sf_errno));
45 : 0 : return -1;
46 : : }
47 : :
48 [ # # # # : 0 : switch (sfi.format & SF_FORMAT_SUBMASK) {
# # ]
49 : :
50 : : case SF_FORMAT_PCM_16:
51 : : case SF_FORMAT_PCM_U8:
52 : : case SF_FORMAT_PCM_S8:
53 : 0 : ss->format = PA_SAMPLE_S16NE;
54 : 0 : break;
55 : :
56 : : case SF_FORMAT_PCM_24:
57 : 0 : ss->format = PA_SAMPLE_S24NE;
58 : 0 : break;
59 : :
60 : : case SF_FORMAT_PCM_32:
61 : 0 : ss->format = PA_SAMPLE_S32NE;
62 : 0 : break;
63 : :
64 : : case SF_FORMAT_ULAW:
65 : 0 : ss->format = PA_SAMPLE_ULAW;
66 : 0 : break;
67 : :
68 : : case SF_FORMAT_ALAW:
69 : 0 : ss->format = PA_SAMPLE_ALAW;
70 : 0 : break;
71 : :
72 : : case SF_FORMAT_FLOAT:
73 : : case SF_FORMAT_DOUBLE:
74 : : default:
75 : 0 : ss->format = PA_SAMPLE_FLOAT32NE;
76 : 0 : break;
77 : : }
78 : :
79 : 0 : ss->rate = (uint32_t) sfi.samplerate;
80 : 0 : ss->channels = (uint8_t) sfi.channels;
81 : :
82 [ # # ]: 0 : if (!pa_sample_spec_valid(ss))
83 : : return -1;
84 : :
85 : 0 : return 0;
86 : : }
87 : :
88 : 0 : int pa_sndfile_write_sample_spec(SF_INFO *sfi, pa_sample_spec *ss) {
89 [ # # ]: 0 : pa_assert(sfi);
90 [ # # ]: 0 : pa_assert(ss);
91 : :
92 : 0 : sfi->samplerate = (int) ss->rate;
93 : 0 : sfi->channels = (int) ss->channels;
94 : :
95 [ # # ]: 0 : if (pa_sample_format_is_le(ss->format) > 0)
96 : 0 : sfi->format = SF_ENDIAN_LITTLE;
97 [ # # ]: 0 : else if (pa_sample_format_is_be(ss->format) > 0)
98 : 0 : sfi->format = SF_ENDIAN_BIG;
99 : :
100 [ # # # # : 0 : switch (ss->format) {
# # # # ]
101 : :
102 : : case PA_SAMPLE_U8:
103 : 0 : ss->format = PA_SAMPLE_S16NE;
104 : 0 : sfi->format = SF_FORMAT_PCM_U8;
105 : 0 : break;
106 : :
107 : : case PA_SAMPLE_S16LE:
108 : : case PA_SAMPLE_S16BE:
109 : 0 : ss->format = PA_SAMPLE_S16NE;
110 : 0 : sfi->format |= SF_FORMAT_PCM_16;
111 : 0 : break;
112 : :
113 : : case PA_SAMPLE_S24LE:
114 : : case PA_SAMPLE_S24BE:
115 : 0 : ss->format = PA_SAMPLE_S24NE;
116 : 0 : sfi->format |= SF_FORMAT_PCM_24;
117 : 0 : break;
118 : :
119 : : case PA_SAMPLE_S24_32LE:
120 : : case PA_SAMPLE_S24_32BE:
121 : 0 : ss->format = PA_SAMPLE_S24_32NE;
122 : 0 : sfi->format |= SF_FORMAT_PCM_32;
123 : 0 : break;
124 : :
125 : : case PA_SAMPLE_S32LE:
126 : : case PA_SAMPLE_S32BE:
127 : 0 : ss->format = PA_SAMPLE_S32NE;
128 : 0 : sfi->format |= SF_FORMAT_PCM_32;
129 : 0 : break;
130 : :
131 : : case PA_SAMPLE_ULAW:
132 : 0 : sfi->format = SF_FORMAT_ULAW;
133 : 0 : break;
134 : :
135 : : case PA_SAMPLE_ALAW:
136 : 0 : sfi->format = SF_FORMAT_ALAW;
137 : 0 : break;
138 : :
139 : : case PA_SAMPLE_FLOAT32LE:
140 : : case PA_SAMPLE_FLOAT32BE:
141 : : default:
142 : 0 : ss->format = PA_SAMPLE_FLOAT32NE;
143 : 0 : sfi->format |= SF_FORMAT_FLOAT;
144 : 0 : break;
145 : : }
146 : :
147 : :
148 [ # # ]: 0 : if (!pa_sample_spec_valid(ss))
149 : : return -1;
150 : :
151 : 0 : return 0;
152 : : }
153 : :
154 : 0 : int pa_sndfile_read_channel_map(SNDFILE *sf, pa_channel_map *cm) {
155 : :
156 : : static const pa_channel_position_t table[] = {
157 : : [SF_CHANNEL_MAP_MONO] = PA_CHANNEL_POSITION_MONO,
158 : : [SF_CHANNEL_MAP_LEFT] = PA_CHANNEL_POSITION_FRONT_LEFT, /* libsndfile distinguishes left and front-left, which we don't */
159 : : [SF_CHANNEL_MAP_RIGHT] = PA_CHANNEL_POSITION_FRONT_RIGHT,
160 : : [SF_CHANNEL_MAP_CENTER] = PA_CHANNEL_POSITION_FRONT_CENTER,
161 : : [SF_CHANNEL_MAP_FRONT_LEFT] = PA_CHANNEL_POSITION_FRONT_LEFT,
162 : : [SF_CHANNEL_MAP_FRONT_RIGHT] = PA_CHANNEL_POSITION_FRONT_RIGHT,
163 : : [SF_CHANNEL_MAP_FRONT_CENTER] = PA_CHANNEL_POSITION_FRONT_CENTER,
164 : : [SF_CHANNEL_MAP_REAR_CENTER] = PA_CHANNEL_POSITION_REAR_CENTER,
165 : : [SF_CHANNEL_MAP_REAR_LEFT] = PA_CHANNEL_POSITION_REAR_LEFT,
166 : : [SF_CHANNEL_MAP_REAR_RIGHT] = PA_CHANNEL_POSITION_REAR_RIGHT,
167 : : [SF_CHANNEL_MAP_LFE] = PA_CHANNEL_POSITION_LFE,
168 : : [SF_CHANNEL_MAP_FRONT_LEFT_OF_CENTER] = PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER,
169 : : [SF_CHANNEL_MAP_FRONT_RIGHT_OF_CENTER] = PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER,
170 : : [SF_CHANNEL_MAP_SIDE_LEFT] = PA_CHANNEL_POSITION_SIDE_LEFT,
171 : : [SF_CHANNEL_MAP_SIDE_RIGHT] = PA_CHANNEL_POSITION_SIDE_RIGHT,
172 : : [SF_CHANNEL_MAP_TOP_CENTER] = PA_CHANNEL_POSITION_TOP_CENTER,
173 : : [SF_CHANNEL_MAP_TOP_FRONT_LEFT] = PA_CHANNEL_POSITION_TOP_FRONT_LEFT,
174 : : [SF_CHANNEL_MAP_TOP_FRONT_RIGHT] = PA_CHANNEL_POSITION_TOP_FRONT_RIGHT,
175 : : [SF_CHANNEL_MAP_TOP_FRONT_CENTER] = PA_CHANNEL_POSITION_TOP_FRONT_CENTER,
176 : : [SF_CHANNEL_MAP_TOP_REAR_LEFT] = PA_CHANNEL_POSITION_TOP_REAR_LEFT,
177 : : [SF_CHANNEL_MAP_TOP_REAR_RIGHT] = PA_CHANNEL_POSITION_TOP_REAR_RIGHT,
178 : : [SF_CHANNEL_MAP_TOP_REAR_CENTER] = PA_CHANNEL_POSITION_TOP_REAR_CENTER
179 : : };
180 : :
181 : : SF_INFO sfi;
182 : : int sf_errno;
183 : : int *channels;
184 : : unsigned c;
185 : :
186 [ # # ]: 0 : pa_assert(sf);
187 [ # # ]: 0 : pa_assert(cm);
188 : :
189 : : pa_zero(sfi);
190 [ # # ]: 0 : if ((sf_errno = sf_command(sf, SFC_GET_CURRENT_SF_INFO, &sfi, sizeof(sfi)))) {
191 : 0 : pa_log_error("sndfile: %s", sf_error_number(sf_errno));
192 : 0 : return -1;
193 : : }
194 : :
195 : 0 : channels = pa_xnew(int, sfi.channels);
196 [ # # ]: 0 : if (!sf_command(sf, SFC_GET_CHANNEL_MAP_INFO, channels, sizeof(channels[0]) * sfi.channels)) {
197 : 0 : pa_xfree(channels);
198 : 0 : return -1;
199 : : }
200 : :
201 : 0 : cm->channels = (uint8_t) sfi.channels;
202 [ # # ]: 0 : for (c = 0; c < cm->channels; c++) {
203 [ # # ]: 0 : if (channels[c] <= SF_CHANNEL_MAP_INVALID ||
204 : : (unsigned) channels[c] >= PA_ELEMENTSOF(table)) {
205 : 0 : pa_xfree(channels);
206 : 0 : return -1;
207 : : }
208 : :
209 : 0 : cm->map[c] = table[channels[c]];
210 : : }
211 : :
212 : 0 : pa_xfree(channels);
213 : :
214 [ # # ]: 0 : if (!pa_channel_map_valid(cm))
215 : : return -1;
216 : :
217 : 0 : return 0;
218 : : }
219 : :
220 : 0 : int pa_sndfile_write_channel_map(SNDFILE *sf, pa_channel_map *cm) {
221 : : static const int table[PA_CHANNEL_POSITION_MAX] = {
222 : : [PA_CHANNEL_POSITION_MONO] = SF_CHANNEL_MAP_MONO,
223 : :
224 : : [PA_CHANNEL_POSITION_FRONT_LEFT] = SF_CHANNEL_MAP_FRONT_LEFT,
225 : : [PA_CHANNEL_POSITION_FRONT_RIGHT] = SF_CHANNEL_MAP_FRONT_RIGHT,
226 : : [PA_CHANNEL_POSITION_FRONT_CENTER] = SF_CHANNEL_MAP_FRONT_CENTER,
227 : :
228 : : [PA_CHANNEL_POSITION_REAR_CENTER] = SF_CHANNEL_MAP_REAR_CENTER,
229 : : [PA_CHANNEL_POSITION_REAR_LEFT] = SF_CHANNEL_MAP_REAR_LEFT,
230 : : [PA_CHANNEL_POSITION_REAR_RIGHT] = SF_CHANNEL_MAP_REAR_RIGHT,
231 : :
232 : : [PA_CHANNEL_POSITION_LFE] = SF_CHANNEL_MAP_LFE,
233 : :
234 : : [PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER] = SF_CHANNEL_MAP_FRONT_LEFT_OF_CENTER,
235 : : [PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER] = SF_CHANNEL_MAP_FRONT_RIGHT_OF_CENTER,
236 : :
237 : : [PA_CHANNEL_POSITION_SIDE_LEFT] = SF_CHANNEL_MAP_SIDE_LEFT,
238 : : [PA_CHANNEL_POSITION_SIDE_RIGHT] = SF_CHANNEL_MAP_SIDE_RIGHT,
239 : :
240 : : [PA_CHANNEL_POSITION_AUX0] = -1,
241 : : [PA_CHANNEL_POSITION_AUX1] = -1,
242 : : [PA_CHANNEL_POSITION_AUX2] = -1,
243 : : [PA_CHANNEL_POSITION_AUX3] = -1,
244 : : [PA_CHANNEL_POSITION_AUX4] = -1,
245 : : [PA_CHANNEL_POSITION_AUX5] = -1,
246 : : [PA_CHANNEL_POSITION_AUX6] = -1,
247 : : [PA_CHANNEL_POSITION_AUX7] = -1,
248 : : [PA_CHANNEL_POSITION_AUX8] = -1,
249 : : [PA_CHANNEL_POSITION_AUX9] = -1,
250 : : [PA_CHANNEL_POSITION_AUX10] = -1,
251 : : [PA_CHANNEL_POSITION_AUX11] = -1,
252 : : [PA_CHANNEL_POSITION_AUX12] = -1,
253 : : [PA_CHANNEL_POSITION_AUX13] = -1,
254 : : [PA_CHANNEL_POSITION_AUX14] = -1,
255 : : [PA_CHANNEL_POSITION_AUX15] = -1,
256 : : [PA_CHANNEL_POSITION_AUX16] = -1,
257 : : [PA_CHANNEL_POSITION_AUX17] = -1,
258 : : [PA_CHANNEL_POSITION_AUX18] = -1,
259 : : [PA_CHANNEL_POSITION_AUX19] = -1,
260 : : [PA_CHANNEL_POSITION_AUX20] = -1,
261 : : [PA_CHANNEL_POSITION_AUX21] = -1,
262 : : [PA_CHANNEL_POSITION_AUX22] = -1,
263 : : [PA_CHANNEL_POSITION_AUX23] = -1,
264 : : [PA_CHANNEL_POSITION_AUX24] = -1,
265 : : [PA_CHANNEL_POSITION_AUX25] = -1,
266 : : [PA_CHANNEL_POSITION_AUX26] = -1,
267 : : [PA_CHANNEL_POSITION_AUX27] = -1,
268 : : [PA_CHANNEL_POSITION_AUX28] = -1,
269 : : [PA_CHANNEL_POSITION_AUX29] = -1,
270 : : [PA_CHANNEL_POSITION_AUX30] = -1,
271 : : [PA_CHANNEL_POSITION_AUX31] = -1,
272 : :
273 : : [PA_CHANNEL_POSITION_TOP_CENTER] = SF_CHANNEL_MAP_TOP_CENTER,
274 : :
275 : : [PA_CHANNEL_POSITION_TOP_FRONT_LEFT] = SF_CHANNEL_MAP_TOP_FRONT_LEFT,
276 : : [PA_CHANNEL_POSITION_TOP_FRONT_RIGHT] = SF_CHANNEL_MAP_TOP_FRONT_RIGHT,
277 : : [PA_CHANNEL_POSITION_TOP_FRONT_CENTER] = SF_CHANNEL_MAP_TOP_FRONT_CENTER ,
278 : :
279 : : [PA_CHANNEL_POSITION_TOP_REAR_LEFT] = SF_CHANNEL_MAP_TOP_REAR_LEFT,
280 : : [PA_CHANNEL_POSITION_TOP_REAR_RIGHT] = SF_CHANNEL_MAP_TOP_REAR_RIGHT,
281 : : [PA_CHANNEL_POSITION_TOP_REAR_CENTER] = SF_CHANNEL_MAP_TOP_REAR_CENTER,
282 : : };
283 : :
284 : : int *channels;
285 : : unsigned c;
286 : :
287 [ # # ]: 0 : pa_assert(sf);
288 [ # # ]: 0 : pa_assert(cm);
289 : :
290 : : /* Suppress channel mapping for the obvious cases */
291 [ # # ][ # # ]: 0 : if (cm->channels == 1 && cm->map[0] == PA_CHANNEL_POSITION_MONO)
292 : : return 0;
293 : :
294 [ # # ][ # # ]: 0 : if (cm->channels == 2 &&
295 [ # # ]: 0 : cm->map[0] == PA_CHANNEL_POSITION_FRONT_LEFT &&
296 : 0 : cm->map[1] == PA_CHANNEL_POSITION_FRONT_RIGHT)
297 : : return 0;
298 : :
299 : 0 : channels = pa_xnew(int, cm->channels);
300 [ # # ]: 0 : for (c = 0; c < cm->channels; c++) {
301 : :
302 [ # # ]: 0 : if (cm->map[c] < 0 ||
303 [ # # ]: 0 : cm->map[c] >= PA_CHANNEL_POSITION_MAX ||
304 : 0 : table[cm->map[c]] < 0) {
305 : 0 : pa_xfree(channels);
306 : 0 : return -1;
307 : : }
308 : :
309 : 0 : channels[c] = table[cm->map[c]];
310 : : }
311 : :
312 [ # # ]: 0 : if (!sf_command(sf, SFC_SET_CHANNEL_MAP_INFO, channels, sizeof(channels[0]) * cm->channels)) {
313 : 0 : pa_xfree(channels);
314 : 0 : return -1;
315 : : }
316 : :
317 : 0 : pa_xfree(channels);
318 : 0 : return 0;
319 : : }
320 : :
321 : 0 : void pa_sndfile_init_proplist(SNDFILE *sf, pa_proplist *p) {
322 : :
323 : : static const char* table[] = {
324 : : [SF_STR_TITLE] = PA_PROP_MEDIA_TITLE,
325 : : [SF_STR_COPYRIGHT] = PA_PROP_MEDIA_COPYRIGHT,
326 : : [SF_STR_SOFTWARE] = PA_PROP_MEDIA_SOFTWARE,
327 : : [SF_STR_ARTIST] = PA_PROP_MEDIA_ARTIST,
328 : : [SF_STR_COMMENT] = "media.comment",
329 : : [SF_STR_DATE] = "media.date"
330 : : };
331 : :
332 : : SF_INFO sfi;
333 : : SF_FORMAT_INFO fi;
334 : : int sf_errno;
335 : : unsigned c;
336 : :
337 [ # # ]: 0 : pa_assert(sf);
338 [ # # ]: 0 : pa_assert(p);
339 : :
340 [ # # ]: 0 : for (c = 0; c < PA_ELEMENTSOF(table); c++) {
341 : : const char *s;
342 : : char *t;
343 : :
344 [ # # ]: 0 : if (!table[c])
345 : 0 : continue;
346 : :
347 [ # # ]: 0 : if (!(s = sf_get_string(sf, c)))
348 : 0 : continue;
349 : :
350 : 0 : t = pa_utf8_filter(s);
351 : 0 : pa_proplist_sets(p, table[c], t);
352 : 0 : pa_xfree(t);
353 : : }
354 : :
355 : : pa_zero(sfi);
356 [ # # ]: 0 : if ((sf_errno = sf_command(sf, SFC_GET_CURRENT_SF_INFO, &sfi, sizeof(sfi)))) {
357 : 0 : pa_log_error("sndfile: %s", sf_error_number(sf_errno));
358 : 0 : return;
359 : : }
360 : :
361 : : pa_zero(fi);
362 : 0 : fi.format = sfi.format;
363 [ # # ][ # # ]: 0 : if (sf_command(sf, SFC_GET_FORMAT_INFO, &fi, sizeof(fi)) == 0 && fi.name) {
364 : : char *t;
365 : :
366 : 0 : t = pa_utf8_filter(fi.name);
367 : 0 : pa_proplist_sets(p, "media.format", t);
368 : 0 : pa_xfree(t);
369 : : }
370 : : }
371 : :
372 : 0 : pa_sndfile_readf_t pa_sndfile_readf_function(const pa_sample_spec *ss) {
373 [ # # ]: 0 : pa_assert(ss);
374 : :
375 [ # # # # : 0 : switch (ss->format) {
# ]
376 : : case PA_SAMPLE_S16NE:
377 : : return (pa_sndfile_readf_t) sf_readf_short;
378 : :
379 : : case PA_SAMPLE_S32NE:
380 : : case PA_SAMPLE_S24_32NE:
381 : 0 : return (pa_sndfile_readf_t) sf_readf_int;
382 : :
383 : : case PA_SAMPLE_FLOAT32NE:
384 : 0 : return (pa_sndfile_readf_t) sf_readf_float;
385 : :
386 : : case PA_SAMPLE_ULAW:
387 : : case PA_SAMPLE_ALAW:
388 : 0 : return NULL;
389 : :
390 : : default:
391 : 0 : pa_assert_not_reached();
392 : : }
393 : : }
394 : :
395 : 0 : pa_sndfile_writef_t pa_sndfile_writef_function(const pa_sample_spec *ss) {
396 [ # # ]: 0 : pa_assert(ss);
397 : :
398 [ # # # # : 0 : switch (ss->format) {
# ]
399 : : case PA_SAMPLE_S16NE:
400 : : return (pa_sndfile_writef_t) sf_writef_short;
401 : :
402 : : case PA_SAMPLE_S32NE:
403 : : case PA_SAMPLE_S24_32NE:
404 : 0 : return (pa_sndfile_writef_t) sf_writef_int;
405 : :
406 : : case PA_SAMPLE_FLOAT32NE:
407 : 0 : return (pa_sndfile_writef_t) sf_writef_float;
408 : :
409 : : case PA_SAMPLE_ULAW:
410 : : case PA_SAMPLE_ALAW:
411 : 0 : return NULL;
412 : :
413 : : default:
414 : 0 : pa_assert_not_reached();
415 : : }
416 : : }
417 : :
418 : 0 : int pa_sndfile_format_from_string(const char *name) {
419 : 0 : int i, count = 0;
420 : :
421 : :
422 [ # # ]: 0 : if (!name[0])
423 : : return -1;
424 : :
425 [ # # ]: 0 : pa_assert_se(sf_command(NULL, SFC_GET_FORMAT_MAJOR_COUNT, &count, sizeof(int)) == 0);
426 : :
427 : : /* First try to match via full type string */
428 [ # # ]: 0 : for (i = 0; i < count; i++) {
429 : : SF_FORMAT_INFO fi;
430 : : pa_zero(fi);
431 : 0 : fi.format = i;
432 : :
433 [ # # ]: 0 : pa_assert_se(sf_command(NULL, SFC_GET_FORMAT_MAJOR, &fi, sizeof(fi)) == 0);
434 : :
435 [ # # ]: 0 : if (strcasecmp(name, fi.name) == 0)
436 : 0 : return fi.format;
437 : : }
438 : :
439 : : /* Then, try to match via the full extension */
440 [ # # ]: 0 : for (i = 0; i < count; i++) {
441 : : SF_FORMAT_INFO fi;
442 : : pa_zero(fi);
443 : 0 : fi.format = i;
444 : :
445 [ # # ]: 0 : pa_assert_se(sf_command(NULL, SFC_GET_FORMAT_MAJOR, &fi, sizeof(fi)) == 0);
446 : :
447 [ # # ]: 0 : if (strcasecmp(name, fi.extension) == 0)
448 : 0 : return fi.format;
449 : : }
450 : :
451 : : /* Then, try to match via the start of the type string */
452 [ # # ]: 0 : for (i = 0; i < count; i++) {
453 : : SF_FORMAT_INFO fi;
454 : : pa_zero(fi);
455 : 0 : fi.format = i;
456 : :
457 [ # # ]: 0 : pa_assert_se(sf_command(NULL, SFC_GET_FORMAT_MAJOR, &fi, sizeof(fi)) == 0);
458 : :
459 [ # # ]: 0 : if (strncasecmp(name, fi.name, strlen(name)) == 0)
460 : 0 : return fi.format;
461 : : }
462 : :
463 : : return -1;
464 : : }
465 : :
466 : 0 : void pa_sndfile_dump_formats(void) {
467 : 0 : int i, count = 0;
468 : :
469 [ # # ]: 0 : pa_assert_se(sf_command(NULL, SFC_GET_FORMAT_MAJOR_COUNT, &count, sizeof(int)) == 0);
470 : :
471 [ # # ]: 0 : for (i = 0; i < count; i++) {
472 : : SF_FORMAT_INFO fi;
473 : : pa_zero(fi);
474 : 0 : fi.format = i;
475 : :
476 [ # # ]: 0 : pa_assert_se(sf_command(NULL, SFC_GET_FORMAT_MAJOR, &fi, sizeof(fi)) == 0);
477 : 0 : printf("%s\t%s\n", fi.extension, fi.name);
478 : : }
479 : 0 : }
|