blob: 8aadbabe9fac393645e5c1c78291689ca2803f9a [file] [log] [blame]
Alexandre Lision7c6f4a62013-09-05 13:27:01 -04001/*
2** Copyright (C) 1999-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
3**
4** This program is free software; you can redistribute it and/or modify
5** it under the terms of the GNU Lesser General Public License as published by
6** the Free Software Foundation; either version 2.1 of the License, or
7** (at your option) any later version.
8**
9** This program is distributed in the hope that it will be useful,
10** but WITHOUT ANY WARRANTY; without even the implied warranty of
11** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12** GNU Lesser General Public License for more details.
13**
14** You should have received a copy of the GNU Lesser General Public License
15** along with this program; if not, write to the Free Software
16** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17*/
18
19#include <config.h>
20
21#include <stdarg.h>
22#include <string.h>
23#include <ctype.h>
24#include <math.h>
25#include <time.h>
26#include <sys/time.h>
27
28#include "sndfile.h"
29#include "sfendian.h"
30#include "common.h"
31
32/*-----------------------------------------------------------------------------------------------
33** psf_log_printf allows libsndfile internal functions to print to an internal logbuffer which
34** can later be displayed.
35** The format specifiers are as for printf but without the field width and other modifiers.
36** Printing is performed to the logbuffer char array of the SF_PRIVATE struct.
37** Printing is done in such a way as to guarantee that the log never overflows the end of the
38** logbuffer array.
39*/
40
41static inline void
42log_putchar (SF_PRIVATE *psf, char ch)
43{ if (psf->logindex < SIGNED_SIZEOF (psf->logbuffer) - 1)
44 { psf->logbuffer [psf->logindex++] = ch ;
45 psf->logbuffer [psf->logindex] = 0 ;
46 } ;
47 return ;
48} /* log_putchar */
49
50void
51psf_log_printf (SF_PRIVATE *psf, const char *format, ...)
52{ va_list ap ;
53 unsigned int u ;
54 int d, tens, shift, width, width_specifier, left_align ;
55 char c, *strptr, istr [5], lead_char, sign_char ;
56
57 va_start (ap, format) ;
58
59 while ((c = *format++))
60 { if (c != '%')
61 { log_putchar (psf, c) ;
62 continue ;
63 } ;
64
65 if (format [0] == '%') /* Handle %% */
66 { log_putchar (psf, '%') ;
67 format ++ ;
68 continue ;
69 } ;
70
71 sign_char = 0 ;
72 left_align = SF_FALSE ;
73 while (1)
74 { switch (format [0])
75 { case ' ' :
76 case '+' :
77 sign_char = format [0] ;
78 format ++ ;
79 continue ;
80
81 case '-' :
82 left_align = SF_TRUE ;
83 format ++ ;
84 continue ;
85
86 default : break ;
87 } ;
88
89 break ;
90 } ;
91
92 if (format [0] == 0)
93 break ;
94
95 lead_char = ' ' ;
96 if (format [0] == '0')
97 lead_char = '0' ;
98
99 width_specifier = 0 ;
100 while ((c = *format++) && isdigit (c))
101 width_specifier = width_specifier * 10 + (c - '0') ;
102
103 switch (c)
104 { case 0 : /* NULL character. */
105 va_end (ap) ;
106 return ;
107
108 case 's': /* string */
109 strptr = va_arg (ap, char *) ;
110 if (strptr == NULL)
111 break ;
112 width_specifier -= strlen (strptr) ;
113 if (left_align == SF_FALSE)
114 while (width_specifier -- > 0)
115 log_putchar (psf, ' ') ;
116 while (*strptr)
117 log_putchar (psf, *strptr++) ;
118 while (width_specifier -- > 0)
119 log_putchar (psf, ' ') ;
120 break ;
121
122 case 'd': /* int */
123 d = va_arg (ap, int) ;
124
125 if (d < 0)
126 { d = -d ;
127 sign_char = '-' ;
128 if (lead_char != '0' && left_align == SF_FALSE)
129 width_specifier -- ;
130 } ;
131
132 tens = 1 ;
133 width = 1 ;
134 while (d / tens >= 10)
135 { tens *= 10 ;
136 width ++ ;
137 } ;
138
139 width_specifier -= width ;
140
141 if (sign_char == ' ')
142 { log_putchar (psf, ' ') ;
143 width_specifier -- ;
144 } ;
145
146 if (left_align == SF_FALSE && lead_char != '0')
147 { if (sign_char == '+')
148 width_specifier -- ;
149
150 while (width_specifier -- > 0)
151 log_putchar (psf, lead_char) ;
152 } ;
153
154 if (sign_char == '+' || sign_char == '-')
155 { log_putchar (psf, sign_char) ;
156 width_specifier -- ;
157 } ;
158
159 if (left_align == SF_FALSE)
160 while (width_specifier -- > 0)
161 log_putchar (psf, lead_char) ;
162
163 while (tens > 0)
164 { log_putchar (psf, '0' + d / tens) ;
165 d %= tens ;
166 tens /= 10 ;
167 } ;
168
169 while (width_specifier -- > 0)
170 log_putchar (psf, lead_char) ;
171 break ;
172
173 case 'D': /* sf_count_t */
174 { sf_count_t D, Tens ;
175
176 D = va_arg (ap, sf_count_t) ;
177
178 if (D == 0)
179 { while (-- width_specifier > 0)
180 log_putchar (psf, lead_char) ;
181 log_putchar (psf, '0') ;
182 break ;
183 }
184 if (D < 0)
185 { log_putchar (psf, '-') ;
186 D = -D ;
187 } ;
188 Tens = 1 ;
189 width = 1 ;
190 while (D / Tens >= 10)
191 { Tens *= 10 ;
192 width ++ ;
193 } ;
194
195 while (width_specifier > width)
196 { log_putchar (psf, lead_char) ;
197 width_specifier-- ;
198 } ;
199
200 while (Tens > 0)
201 { log_putchar (psf, '0' + D / Tens) ;
202 D %= Tens ;
203 Tens /= 10 ;
204 } ;
205 } ;
206 break ;
207
208 case 'u': /* unsigned int */
209 u = va_arg (ap, unsigned int) ;
210
211 tens = 1 ;
212 width = 1 ;
213 while (u / tens >= 10)
214 { tens *= 10 ;
215 width ++ ;
216 } ;
217
218 width_specifier -= width ;
219
220 if (sign_char == ' ')
221 { log_putchar (psf, ' ') ;
222 width_specifier -- ;
223 } ;
224
225 if (left_align == SF_FALSE && lead_char != '0')
226 { if (sign_char == '+')
227 width_specifier -- ;
228
229 while (width_specifier -- > 0)
230 log_putchar (psf, lead_char) ;
231 } ;
232
233 if (sign_char == '+' || sign_char == '-')
234 { log_putchar (psf, sign_char) ;
235 width_specifier -- ;
236 } ;
237
238 if (left_align == SF_FALSE)
239 while (width_specifier -- > 0)
240 log_putchar (psf, lead_char) ;
241
242 while (tens > 0)
243 { log_putchar (psf, '0' + u / tens) ;
244 u %= tens ;
245 tens /= 10 ;
246 } ;
247
248 while (width_specifier -- > 0)
249 log_putchar (psf, lead_char) ;
250 break ;
251
252 case 'c': /* char */
253 c = va_arg (ap, int) & 0xFF ;
254 log_putchar (psf, c) ;
255 break ;
256
257 case 'x': /* hex */
258 case 'X': /* hex */
259 d = va_arg (ap, int) ;
260
261 if (d == 0)
262 { while (--width_specifier > 0)
263 log_putchar (psf, lead_char) ;
264 log_putchar (psf, '0') ;
265 break ;
266 } ;
267 shift = 28 ;
268 width = (width_specifier < 8) ? 8 : width_specifier ;
269 while (! ((0xF << shift) & d))
270 { shift -= 4 ;
271 width -- ;
272 } ;
273
274 while (width > 0 && width_specifier > width)
275 { log_putchar (psf, lead_char) ;
276 width_specifier-- ;
277 } ;
278
279 while (shift >= 0)
280 { c = (d >> shift) & 0xF ;
281 log_putchar (psf, (c > 9) ? c + 'A' - 10 : c + '0') ;
282 shift -= 4 ;
283 } ;
284 break ;
285
286 case 'M': /* int2str */
287 d = va_arg (ap, int) ;
288 if (CPU_IS_LITTLE_ENDIAN)
289 { istr [0] = d & 0xFF ;
290 istr [1] = (d >> 8) & 0xFF ;
291 istr [2] = (d >> 16) & 0xFF ;
292 istr [3] = (d >> 24) & 0xFF ;
293 }
294 else
295 { istr [3] = d & 0xFF ;
296 istr [2] = (d >> 8) & 0xFF ;
297 istr [1] = (d >> 16) & 0xFF ;
298 istr [0] = (d >> 24) & 0xFF ;
299 } ;
300 istr [4] = 0 ;
301 strptr = istr ;
302 while (*strptr)
303 { c = *strptr++ ;
304 log_putchar (psf, c) ;
305 } ;
306 break ;
307
308 default :
309 log_putchar (psf, '*') ;
310 log_putchar (psf, c) ;
311 log_putchar (psf, '*') ;
312 break ;
313 } /* switch */
314 } /* while */
315
316 va_end (ap) ;
317 return ;
318} /* psf_log_printf */
319
320/*-----------------------------------------------------------------------------------------------
321** ASCII header printf functions.
322** Some formats (ie NIST) use ascii text in their headers.
323** Format specifiers are the same as the standard printf specifiers (uses vsnprintf).
324** If this generates a compile error on any system, the author should be notified
325** so an alternative vsnprintf can be provided.
326*/
327
328void
329psf_asciiheader_printf (SF_PRIVATE *psf, const char *format, ...)
330{ va_list argptr ;
331 int maxlen ;
332 char *start ;
333
334 maxlen = strlen ((char*) psf->header) ;
335 start = ((char*) psf->header) + maxlen ;
336 maxlen = sizeof (psf->header) - maxlen ;
337
338 va_start (argptr, format) ;
339 vsnprintf (start, maxlen, format, argptr) ;
340 va_end (argptr) ;
341
342 /* Make sure the string is properly terminated. */
343 start [maxlen - 1] = 0 ;
344
345 psf->headindex = strlen ((char*) psf->header) ;
346
347 return ;
348} /* psf_asciiheader_printf */
349
350/*-----------------------------------------------------------------------------------------------
351** Binary header writing functions. Returns number of bytes written.
352**
353** Format specifiers for psf_binheader_writef are as follows
354** m - marker - four bytes - no endian manipulation
355**
356** e - all following numerical values will be little endian
357** E - all following numerical values will be big endian
358**
359** t - all following O types will be truncated to 4 bytes
360** T - switch off truncation of all following O types
361**
362** 1 - single byte value
363** 2 - two byte value
364** 3 - three byte value
365** 4 - four byte value
366** 8 - eight byte value (sometimes written as 4 bytes)
367**
368** s - string preceded by a four byte length
369** S - string including null terminator
370** f - floating point data
371** d - double precision floating point data
372** h - 16 binary bytes value
373**
374** b - binary data (see below)
375** z - zero bytes (ses below)
376** j - jump forwards or backwards
377**
378** To write a word followed by an int (both little endian) use:
379** psf_binheader_writef ("e24", wordval, longval) ;
380**
381** To write binary data use:
382** psf_binheader_writef ("b", &bindata, sizeof (bindata)) ;
383**
384** To write N zero bytes use:
385** NOTE: due to platform issues (ie x86-64) you should cast the
386** argument to size_t or ensure the variable type is size_t.
387** psf_binheader_writef ("z", N) ;
388*/
389
390/* These macros may seem a bit messy but do prevent problems with processors which
391** seg. fault when asked to write an int or short to a non-int/short aligned address.
392*/
393
394static inline void
395header_put_byte (SF_PRIVATE *psf, char x)
396{ if (psf->headindex < SIGNED_SIZEOF (psf->header) - 1)
397 psf->header [psf->headindex++] = x ;
398} /* header_put_byte */
399
400#if (CPU_IS_BIG_ENDIAN == 1)
401static inline void
402header_put_marker (SF_PRIVATE *psf, int x)
403{ if (psf->headindex < SIGNED_SIZEOF (psf->header) - 4)
404 { psf->header [psf->headindex++] = (x >> 24) ;
405 psf->header [psf->headindex++] = (x >> 16) ;
406 psf->header [psf->headindex++] = (x >> 8) ;
407 psf->header [psf->headindex++] = x ;
408 } ;
409} /* header_put_marker */
410
411#elif (CPU_IS_LITTLE_ENDIAN == 1)
412static inline void
413header_put_marker (SF_PRIVATE *psf, int x)
414{ if (psf->headindex < SIGNED_SIZEOF (psf->header) - 4)
415 { psf->header [psf->headindex++] = x ;
416 psf->header [psf->headindex++] = (x >> 8) ;
417 psf->header [psf->headindex++] = (x >> 16) ;
418 psf->header [psf->headindex++] = (x >> 24) ;
419 } ;
420} /* header_put_marker */
421
422#else
423# error "Cannot determine endian-ness of processor."
424#endif
425
426
427static inline void
428header_put_be_short (SF_PRIVATE *psf, int x)
429{ if (psf->headindex < SIGNED_SIZEOF (psf->header) - 2)
430 { psf->header [psf->headindex++] = (x >> 8) ;
431 psf->header [psf->headindex++] = x ;
432 } ;
433} /* header_put_be_short */
434
435static inline void
436header_put_le_short (SF_PRIVATE *psf, int x)
437{ if (psf->headindex < SIGNED_SIZEOF (psf->header) - 2)
438 { psf->header [psf->headindex++] = x ;
439 psf->header [psf->headindex++] = (x >> 8) ;
440 } ;
441} /* header_put_le_short */
442
443static inline void
444header_put_be_3byte (SF_PRIVATE *psf, int x)
445{ if (psf->headindex < SIGNED_SIZEOF (psf->header) - 3)
446 { psf->header [psf->headindex++] = (x >> 16) ;
447 psf->header [psf->headindex++] = (x >> 8) ;
448 psf->header [psf->headindex++] = x ;
449 } ;
450} /* header_put_be_3byte */
451
452static inline void
453header_put_le_3byte (SF_PRIVATE *psf, int x)
454{ if (psf->headindex < SIGNED_SIZEOF (psf->header) - 3)
455 { psf->header [psf->headindex++] = x ;
456 psf->header [psf->headindex++] = (x >> 8) ;
457 psf->header [psf->headindex++] = (x >> 16) ;
458 } ;
459} /* header_put_le_3byte */
460
461static inline void
462header_put_be_int (SF_PRIVATE *psf, int x)
463{ if (psf->headindex < SIGNED_SIZEOF (psf->header) - 4)
464 { psf->header [psf->headindex++] = (x >> 24) ;
465 psf->header [psf->headindex++] = (x >> 16) ;
466 psf->header [psf->headindex++] = (x >> 8) ;
467 psf->header [psf->headindex++] = x ;
468 } ;
469} /* header_put_be_int */
470
471static inline void
472header_put_le_int (SF_PRIVATE *psf, int x)
473{ if (psf->headindex < SIGNED_SIZEOF (psf->header) - 4)
474 { psf->header [psf->headindex++] = x ;
475 psf->header [psf->headindex++] = (x >> 8) ;
476 psf->header [psf->headindex++] = (x >> 16) ;
477 psf->header [psf->headindex++] = (x >> 24) ;
478 } ;
479} /* header_put_le_int */
480
481#if (SIZEOF_SF_COUNT_T == 4)
482
483static inline void
484header_put_be_8byte (SF_PRIVATE *psf, sf_count_t x)
485{ if (psf->headindex < SIGNED_SIZEOF (psf->header) - 8)
486 { psf->header [psf->headindex++] = 0 ;
487 psf->header [psf->headindex++] = 0 ;
488 psf->header [psf->headindex++] = 0 ;
489 psf->header [psf->headindex++] = 0 ;
490 psf->header [psf->headindex++] = (x >> 24) ;
491 psf->header [psf->headindex++] = (x >> 16) ;
492 psf->header [psf->headindex++] = (x >> 8) ;
493 psf->header [psf->headindex++] = x ;
494 } ;
495} /* header_put_be_8byte */
496
497static inline void
498header_put_le_8byte (SF_PRIVATE *psf, sf_count_t x)
499{ if (psf->headindex < SIGNED_SIZEOF (psf->header) - 8)
500 { psf->header [psf->headindex++] = x ;
501 psf->header [psf->headindex++] = (x >> 8) ;
502 psf->header [psf->headindex++] = (x >> 16) ;
503 psf->header [psf->headindex++] = (x >> 24) ;
504 psf->header [psf->headindex++] = 0 ;
505 psf->header [psf->headindex++] = 0 ;
506 psf->header [psf->headindex++] = 0 ;
507 psf->header [psf->headindex++] = 0 ;
508 } ;
509} /* header_put_le_8byte */
510
511#elif (SIZEOF_SF_COUNT_T == 8)
512
513static inline void
514header_put_be_8byte (SF_PRIVATE *psf, sf_count_t x)
515{ if (psf->headindex < SIGNED_SIZEOF (psf->header) - 8)
516 { psf->header [psf->headindex++] = (x >> 56) ;
517 psf->header [psf->headindex++] = (x >> 48) ;
518 psf->header [psf->headindex++] = (x >> 40) ;
519 psf->header [psf->headindex++] = (x >> 32) ;
520 psf->header [psf->headindex++] = (x >> 24) ;
521 psf->header [psf->headindex++] = (x >> 16) ;
522 psf->header [psf->headindex++] = (x >> 8) ;
523 psf->header [psf->headindex++] = x ;
524 } ;
525} /* header_put_be_8byte */
526
527static inline void
528header_put_le_8byte (SF_PRIVATE *psf, sf_count_t x)
529{ if (psf->headindex < SIGNED_SIZEOF (psf->header) - 8)
530 { psf->header [psf->headindex++] = x ;
531 psf->header [psf->headindex++] = (x >> 8) ;
532 psf->header [psf->headindex++] = (x >> 16) ;
533 psf->header [psf->headindex++] = (x >> 24) ;
534 psf->header [psf->headindex++] = (x >> 32) ;
535 psf->header [psf->headindex++] = (x >> 40) ;
536 psf->header [psf->headindex++] = (x >> 48) ;
537 psf->header [psf->headindex++] = (x >> 56) ;
538 } ;
539} /* header_put_le_8byte */
540
541#else
542#error "SIZEOF_SF_COUNT_T is not defined."
543#endif
544
545int
546psf_binheader_writef (SF_PRIVATE *psf, const char *format, ...)
547{ va_list argptr ;
548 sf_count_t countdata ;
549 unsigned long longdata ;
550 unsigned int data ;
551 float floatdata ;
552 double doubledata ;
553 void *bindata ;
554 size_t size ;
555 char c, *strptr ;
556 int count = 0, trunc_8to4 ;
557
558 trunc_8to4 = SF_FALSE ;
559
560 va_start (argptr, format) ;
561
562 while ((c = *format++))
563 { switch (c)
564 { case ' ' : /* Do nothing. Just used to space out format string. */
565 break ;
566
567 case 'e' : /* All conversions are now from LE to host. */
568 psf->rwf_endian = SF_ENDIAN_LITTLE ;
569 break ;
570
571 case 'E' : /* All conversions are now from BE to host. */
572 psf->rwf_endian = SF_ENDIAN_BIG ;
573 break ;
574
575 case 't' : /* All 8 byte values now get written as 4 bytes. */
576 trunc_8to4 = SF_TRUE ;
577 break ;
578
579 case 'T' : /* All 8 byte values now get written as 8 bytes. */
580 trunc_8to4 = SF_FALSE ;
581 break ;
582
583 case 'm' :
584 data = va_arg (argptr, unsigned int) ;
585 header_put_marker (psf, data) ;
586 count += 4 ;
587 break ;
588
589 case '1' :
590 data = va_arg (argptr, unsigned int) ;
591 header_put_byte (psf, data) ;
592 count += 1 ;
593 break ;
594
595 case '2' :
596 data = va_arg (argptr, unsigned int) ;
597 if (psf->rwf_endian == SF_ENDIAN_BIG)
598 { header_put_be_short (psf, data) ;
599 }
600 else
601 { header_put_le_short (psf, data) ;
602 } ;
603 count += 2 ;
604 break ;
605
606 case '3' : /* tribyte */
607 data = va_arg (argptr, unsigned int) ;
608 if (psf->rwf_endian == SF_ENDIAN_BIG)
609 { header_put_be_3byte (psf, data) ;
610 }
611 else
612 { header_put_le_3byte (psf, data) ;
613 } ;
614 count += 3 ;
615 break ;
616
617 case '4' :
618 data = va_arg (argptr, unsigned int) ;
619 if (psf->rwf_endian == SF_ENDIAN_BIG)
620 { header_put_be_int (psf, data) ;
621 }
622 else
623 { header_put_le_int (psf, data) ;
624 } ;
625 count += 4 ;
626 break ;
627
628 case '8' :
629 countdata = va_arg (argptr, sf_count_t) ;
630 if (psf->rwf_endian == SF_ENDIAN_BIG && trunc_8to4 == SF_FALSE)
631 { header_put_be_8byte (psf, countdata) ;
632 count += 8 ;
633 }
634 else if (psf->rwf_endian == SF_ENDIAN_LITTLE && trunc_8to4 == SF_FALSE)
635 { header_put_le_8byte (psf, countdata) ;
636 count += 8 ;
637 }
638 else if (psf->rwf_endian == SF_ENDIAN_BIG && trunc_8to4 == SF_TRUE)
639 { longdata = countdata & 0xFFFFFFFF ;
640 header_put_be_int (psf, longdata) ;
641 count += 4 ;
642 }
643 else if (psf->rwf_endian == SF_ENDIAN_LITTLE && trunc_8to4 == SF_TRUE)
644 { longdata = countdata & 0xFFFFFFFF ;
645 header_put_le_int (psf, longdata) ;
646 count += 4 ;
647 }
648 break ;
649
650 case 'f' :
651 /* Floats are passed as doubles. Is this always true? */
652 floatdata = (float) va_arg (argptr, double) ;
653 if (psf->rwf_endian == SF_ENDIAN_BIG)
654 float32_be_write (floatdata, psf->header + psf->headindex) ;
655 else
656 float32_le_write (floatdata, psf->header + psf->headindex) ;
657 psf->headindex += 4 ;
658 count += 4 ;
659 break ;
660
661 case 'd' :
662 doubledata = va_arg (argptr, double) ;
663 if (psf->rwf_endian == SF_ENDIAN_BIG)
664 double64_be_write (doubledata, psf->header + psf->headindex) ;
665 else
666 double64_le_write (doubledata, psf->header + psf->headindex) ;
667 psf->headindex += 8 ;
668 count += 8 ;
669 break ;
670
671 case 's' :
672 /* Write a C string (guaranteed to have a zero terminator). */
673 strptr = va_arg (argptr, char *) ;
674 size = strlen (strptr) + 1 ;
675 size += (size & 1) ;
676 if (psf->rwf_endian == SF_ENDIAN_BIG)
677 header_put_be_int (psf, size) ;
678 else
679 header_put_le_int (psf, size) ;
680 memcpy (&(psf->header [psf->headindex]), strptr, size) ;
681 psf->headindex += size ;
682 psf->header [psf->headindex - 1] = 0 ;
683 count += 4 + size ;
684 break ;
685
686 case 'S' :
687 /*
688 ** Write an AIFF style string (no zero terminator but possibly
689 ** an extra pad byte if the string length is odd).
690 */
691 strptr = va_arg (argptr, char *) ;
692 size = strlen (strptr) ;
693 if (psf->rwf_endian == SF_ENDIAN_BIG)
694 header_put_be_int (psf, size) ;
695 else
696 header_put_le_int (psf, size) ;
697 memcpy (&(psf->header [psf->headindex]), strptr, size + 1) ;
698 size += (size & 1) ;
699 psf->headindex += size ;
700 psf->header [psf->headindex] = 0 ;
701 count += 4 + size ;
702 break ;
703
704 case 'b' :
705 bindata = va_arg (argptr, void *) ;
706 size = va_arg (argptr, size_t) ;
707 memcpy (&(psf->header [psf->headindex]), bindata, size) ;
708 psf->headindex += size ;
709 count += size ;
710 break ;
711
712 case 'z' :
713 size = va_arg (argptr, size_t) ;
714 count += size ;
715 while (size)
716 { psf->header [psf->headindex] = 0 ;
717 psf->headindex ++ ;
718 size -- ;
719 } ;
720 break ;
721
722 case 'h' :
723 bindata = va_arg (argptr, void *) ;
724 memcpy (&(psf->header [psf->headindex]), bindata, 16) ;
725 psf->headindex += 16 ;
726 count += 16 ;
727 break ;
728
729 case 'j' :
730 size = va_arg (argptr, size_t) ;
731 psf->headindex += size ;
732 count = size ;
733 break ;
734
735 default :
736 psf_log_printf (psf, "*** Invalid format specifier `%c'\n", c) ;
737 psf->error = SFE_INTERNAL ;
738 break ;
739 } ;
740 } ;
741
742 va_end (argptr) ;
743 return count ;
744} /* psf_binheader_writef */
745
746/*-----------------------------------------------------------------------------------------------
747** Binary header reading functions. Returns number of bytes read.
748**
749** Format specifiers are the same as for header write function above with the following
750** additions:
751**
752** p - jump a given number of position from start of file.
753**
754** If format is NULL, psf_binheader_readf returns the current offset.
755*/
756
757#if (CPU_IS_BIG_ENDIAN == 1)
758#define GET_MARKER(ptr) ( ((ptr) [0] << 24) | ((ptr) [1] << 16) | \
759 ((ptr) [2] << 8) | ((ptr) [3]) )
760
761#elif (CPU_IS_LITTLE_ENDIAN == 1)
762#define GET_MARKER(ptr) ( ((ptr) [0]) | ((ptr) [1] << 8) | \
763 ((ptr) [2] << 16) | ((ptr) [3] << 24) )
764
765#else
766# error "Cannot determine endian-ness of processor."
767#endif
768
769#define GET_LE_SHORT(ptr) ( ((ptr) [1] << 8) | ((ptr) [0]) )
770#define GET_BE_SHORT(ptr) ( ((ptr) [0] << 8) | ((ptr) [1]) )
771
772#define GET_LE_3BYTE(ptr) ( ((ptr) [2] << 16) | ((ptr) [1] << 8) | ((ptr) [0]) )
773#define GET_BE_3BYTE(ptr) ( ((ptr) [0] << 16) | ((ptr) [1] << 8) | ((ptr) [2]) )
774
775#define GET_LE_INT(ptr) ( ((ptr) [3] << 24) | ((ptr) [2] << 16) | \
776 ((ptr) [1] << 8) | ((ptr) [0]) )
777
778#define GET_BE_INT(ptr) ( ((ptr) [0] << 24) | ((ptr) [1] << 16) | \
779 ((ptr) [2] << 8) | ((ptr) [3]) )
780
781#define GET_LE_8BYTE(ptr) ( (((sf_count_t) (ptr) [7]) << 56) | (((sf_count_t) (ptr) [6]) << 48) | \
782 (((sf_count_t) (ptr) [5]) << 40) | (((sf_count_t) (ptr) [4]) << 32) | \
783 (((sf_count_t) (ptr) [3]) << 24) | (((sf_count_t) (ptr) [2]) << 16) | \
784 (((sf_count_t) (ptr) [1]) << 8 ) | ((ptr) [0]))
785
786#define GET_BE_8BYTE(ptr) ( (((sf_count_t) (ptr) [0]) << 56) | (((sf_count_t) (ptr) [1]) << 48) | \
787 (((sf_count_t) (ptr) [2]) << 40) | (((sf_count_t) (ptr) [3]) << 32) | \
788 (((sf_count_t) (ptr) [4]) << 24) | (((sf_count_t) (ptr) [5]) << 16) | \
789 (((sf_count_t) (ptr) [6]) << 8 ) | ((ptr) [7]))
790
791
792
793static int
794header_read (SF_PRIVATE *psf, void *ptr, int bytes)
795{ int count = 0 ;
796
797 if (psf->headindex >= SIGNED_SIZEOF (psf->header))
798 { memset (ptr, 0, SIGNED_SIZEOF (psf->header) - psf->headindex) ;
799
800 /* This is the best that we can do. */
801 psf_fseek (psf, bytes, SEEK_CUR) ;
802 return bytes ;
803 } ;
804
805 if (psf->headindex + bytes > SIGNED_SIZEOF (psf->header))
806 { int most ;
807
808 most = SIGNED_SIZEOF (psf->header) - psf->headindex ;
809 psf_fread (psf->header + psf->headend, 1, most, psf) ;
810 memset ((char *) ptr + most, 0, bytes - most) ;
811
812 psf_fseek (psf, bytes - most, SEEK_CUR) ;
813 return bytes ;
814 } ;
815
816 if (psf->headindex + bytes > psf->headend)
817 { count = psf_fread (psf->header + psf->headend, 1, bytes - (psf->headend - psf->headindex), psf) ;
818 if (count != bytes - (int) (psf->headend - psf->headindex))
819 { psf_log_printf (psf, "Error : psf_fread returned short count.\n") ;
820 return 0 ;
821 } ;
822 psf->headend += count ;
823 } ;
824
825 memcpy (ptr, psf->header + psf->headindex, bytes) ;
826 psf->headindex += bytes ;
827
828 return bytes ;
829} /* header_read */
830
831static void
832header_seek (SF_PRIVATE *psf, sf_count_t position, int whence)
833{
834
835 switch (whence)
836 { case SEEK_SET :
837 if (position > SIGNED_SIZEOF (psf->header))
838 { /* Too much header to cache so just seek instead. */
839 psf_fseek (psf, position, whence) ;
840 return ;
841 } ;
842 if (position > psf->headend)
843 psf->headend += psf_fread (psf->header + psf->headend, 1, position - psf->headend, psf) ;
844 psf->headindex = position ;
845 break ;
846
847 case SEEK_CUR :
848 if (psf->headindex + position < 0)
849 break ;
850
851 if (psf->headindex >= SIGNED_SIZEOF (psf->header))
852 { psf_fseek (psf, position, whence) ;
853 return ;
854 } ;
855
856 if (psf->headindex + position <= psf->headend)
857 { psf->headindex += position ;
858 break ;
859 } ;
860
861 if (psf->headindex + position > SIGNED_SIZEOF (psf->header))
862 { /* Need to jump this without caching it. */
863 psf->headindex = psf->headend ;
864 psf_fseek (psf, position, SEEK_CUR) ;
865 break ;
866 } ;
867
868 psf->headend += psf_fread (psf->header + psf->headend, 1, position - (psf->headend - psf->headindex), psf) ;
869 psf->headindex = psf->headend ;
870 break ;
871
872 case SEEK_END :
873 default :
874 psf_log_printf (psf, "Bad whence param in header_seek().\n") ;
875 break ;
876 } ;
877
878 return ;
879} /* header_seek */
880
881static int
882header_gets (SF_PRIVATE *psf, char *ptr, int bufsize)
883{
884 int k ;
885
886 for (k = 0 ; k < bufsize - 1 ; k++)
887 { if (psf->headindex < psf->headend)
888 { ptr [k] = psf->header [psf->headindex] ;
889 psf->headindex ++ ;
890 }
891 else
892 { psf->headend += psf_fread (psf->header + psf->headend, 1, 1, psf) ;
893 ptr [k] = psf->header [psf->headindex] ;
894 psf->headindex = psf->headend ;
895 } ;
896
897 if (ptr [k] == '\n')
898 break ;
899 } ;
900
901 ptr [k] = 0 ;
902
903 return k ;
904} /* header_gets */
905
906int
907psf_binheader_readf (SF_PRIVATE *psf, char const *format, ...)
908{ va_list argptr ;
909 sf_count_t *countptr, countdata ;
910 unsigned char *ucptr, sixteen_bytes [16] ;
911 unsigned int *intptr, intdata ;
912 unsigned short *shortptr ;
913 char *charptr ;
914 float *floatptr ;
915 double *doubleptr ;
916 char c ;
917 int byte_count = 0, count ;
918
919 if (! format)
920 return psf_ftell (psf) ;
921
922 va_start (argptr, format) ;
923
924 while ((c = *format++))
925 { switch (c)
926 { case 'e' : /* All conversions are now from LE to host. */
927 psf->rwf_endian = SF_ENDIAN_LITTLE ;
928 break ;
929
930 case 'E' : /* All conversions are now from BE to host. */
931 psf->rwf_endian = SF_ENDIAN_BIG ;
932 break ;
933
934 case 'm' :
935 intptr = va_arg (argptr, unsigned int*) ;
936 ucptr = (unsigned char*) intptr ;
937 byte_count += header_read (psf, ucptr, sizeof (int)) ;
938 *intptr = GET_MARKER (ucptr) ;
939 break ;
940
941 case 'h' :
942 intptr = va_arg (argptr, unsigned int*) ;
943 ucptr = (unsigned char*) intptr ;
944 byte_count += header_read (psf, sixteen_bytes, sizeof (sixteen_bytes)) ;
945 { int k ;
946 intdata = 0 ;
947 for (k = 0 ; k < 16 ; k++)
948 intdata ^= sixteen_bytes [k] << k ;
949 }
950 *intptr = intdata ;
951 break ;
952
953 case '1' :
954 charptr = va_arg (argptr, char*) ;
955 *charptr = 0 ;
956 byte_count += header_read (psf, charptr, sizeof (char)) ;
957 break ;
958
959 case '2' :
960 shortptr = va_arg (argptr, unsigned short*) ;
961 *shortptr = 0 ;
962 ucptr = (unsigned char*) shortptr ;
963 byte_count += header_read (psf, ucptr, sizeof (short)) ;
964 if (psf->rwf_endian == SF_ENDIAN_BIG)
965 *shortptr = GET_BE_SHORT (ucptr) ;
966 else
967 *shortptr = GET_LE_SHORT (ucptr) ;
968 break ;
969
970 case '3' :
971 intptr = va_arg (argptr, unsigned int*) ;
972 *intptr = 0 ;
973 byte_count += header_read (psf, sixteen_bytes, 3) ;
974 if (psf->rwf_endian == SF_ENDIAN_BIG)
975 *intptr = GET_BE_3BYTE (sixteen_bytes) ;
976 else
977 *intptr = GET_LE_3BYTE (sixteen_bytes) ;
978 break ;
979
980 case '4' :
981 intptr = va_arg (argptr, unsigned int*) ;
982 *intptr = 0 ;
983 ucptr = (unsigned char*) intptr ;
984 byte_count += header_read (psf, ucptr, sizeof (int)) ;
985 if (psf->rwf_endian == SF_ENDIAN_BIG)
986 *intptr = GET_BE_INT (ucptr) ;
987 else
988 *intptr = GET_LE_INT (ucptr) ;
989 break ;
990
991 case '8' :
992 countptr = va_arg (argptr, sf_count_t *) ;
993 *countptr = 0 ;
994 byte_count += header_read (psf, sixteen_bytes, 8) ;
995 if (psf->rwf_endian == SF_ENDIAN_BIG)
996 countdata = GET_BE_8BYTE (sixteen_bytes) ;
997 else
998 countdata = GET_LE_8BYTE (sixteen_bytes) ;
999 *countptr = countdata ;
1000 break ;
1001
1002 case 'f' : /* Float conversion */
1003 floatptr = va_arg (argptr, float *) ;
1004 *floatptr = 0.0 ;
1005 byte_count += header_read (psf, floatptr, sizeof (float)) ;
1006 if (psf->rwf_endian == SF_ENDIAN_BIG)
1007 *floatptr = float32_be_read ((unsigned char*) floatptr) ;
1008 else
1009 *floatptr = float32_le_read ((unsigned char*) floatptr) ;
1010 break ;
1011
1012 case 'd' : /* double conversion */
1013 doubleptr = va_arg (argptr, double *) ;
1014 *doubleptr = 0.0 ;
1015 byte_count += header_read (psf, doubleptr, sizeof (double)) ;
1016 if (psf->rwf_endian == SF_ENDIAN_BIG)
1017 *doubleptr = double64_be_read ((unsigned char*) doubleptr) ;
1018 else
1019 *doubleptr = double64_le_read ((unsigned char*) doubleptr) ;
1020 break ;
1021
1022 case 's' :
1023 psf_log_printf (psf, "Format conversion 's' not implemented yet.\n") ;
1024 /*
1025 strptr = va_arg (argptr, char *) ;
1026 size = strlen (strptr) + 1 ;
1027 size += (size & 1) ;
1028 longdata = H2LE_INT (size) ;
1029 get_int (psf, longdata) ;
1030 memcpy (&(psf->header [psf->headindex]), strptr, size) ;
1031 psf->headindex += size ;
1032 */
1033 break ;
1034
1035 case 'b' :
1036 charptr = va_arg (argptr, char*) ;
1037 count = va_arg (argptr, size_t) ;
1038 if (count > 0)
1039 byte_count += header_read (psf, charptr, count) ;
1040 break ;
1041
1042 case 'G' :
1043 charptr = va_arg (argptr, char*) ;
1044 count = va_arg (argptr, size_t) ;
1045 if (count > 0)
1046 byte_count += header_gets (psf, charptr, count) ;
1047 break ;
1048
1049 case 'z' :
1050 psf_log_printf (psf, "Format conversion 'z' not implemented yet.\n") ;
1051 /*
1052 size = va_arg (argptr, size_t) ;
1053 while (size)
1054 { psf->header [psf->headindex] = 0 ;
1055 psf->headindex ++ ;
1056 size -- ;
1057 } ;
1058 */
1059 break ;
1060
1061 case 'p' :
1062 /* Get the seek position first. */
1063 count = va_arg (argptr, size_t) ;
1064 header_seek (psf, count, SEEK_SET) ;
1065 byte_count = count ;
1066 break ;
1067
1068 case 'j' :
1069 /* Get the seek position first. */
1070 count = va_arg (argptr, size_t) ;
1071 header_seek (psf, count, SEEK_CUR) ;
1072 byte_count += count ;
1073 break ;
1074
1075 default :
1076 psf_log_printf (psf, "*** Invalid format specifier `%c'\n", c) ;
1077 psf->error = SFE_INTERNAL ;
1078 break ;
1079 } ;
1080 } ;
1081
1082 va_end (argptr) ;
1083
1084 return byte_count ;
1085} /* psf_binheader_readf */
1086
1087/*-----------------------------------------------------------------------------------------------
1088*/
1089
1090sf_count_t
1091psf_default_seek (SF_PRIVATE *psf, int UNUSED (mode), sf_count_t samples_from_start)
1092{ sf_count_t position, retval ;
1093
1094 if (! (psf->blockwidth && psf->dataoffset >= 0))
1095 { psf->error = SFE_BAD_SEEK ;
1096 return PSF_SEEK_ERROR ;
1097 } ;
1098
1099 if (! psf->sf.seekable)
1100 { psf->error = SFE_NOT_SEEKABLE ;
1101 return PSF_SEEK_ERROR ;
1102 } ;
1103
1104 position = psf->dataoffset + psf->blockwidth * samples_from_start ;
1105
1106 if ((retval = psf_fseek (psf, position, SEEK_SET)) != position)
1107 { psf->error = SFE_SEEK_FAILED ;
1108 return PSF_SEEK_ERROR ;
1109 } ;
1110
1111 return samples_from_start ;
1112} /* psf_default_seek */
1113
1114/*-----------------------------------------------------------------------------------------------
1115*/
1116
1117void
1118psf_hexdump (const void *ptr, int len)
1119{ const char *data ;
1120 char ascii [17] ;
1121 int k, m ;
1122
1123 if ((data = ptr) == NULL)
1124 return ;
1125 if (len <= 0)
1126 return ;
1127
1128 puts ("") ;
1129 for (k = 0 ; k < len ; k += 16)
1130 { memset (ascii, ' ', sizeof (ascii)) ;
1131
1132 printf ("%08X: ", k) ;
1133 for (m = 0 ; m < 16 && k + m < len ; m++)
1134 { printf (m == 8 ? " %02X " : "%02X ", data [k + m] & 0xFF) ;
1135 ascii [m] = psf_isprint (data [k + m]) ? data [k + m] : '.' ;
1136 } ;
1137
1138 if (m <= 8) printf (" ") ;
1139 for ( ; m < 16 ; m++) printf (" ") ;
1140
1141 ascii [16] = 0 ;
1142 printf (" %s\n", ascii) ;
1143 } ;
1144
1145 puts ("") ;
1146} /* psf_hexdump */
1147
1148void
1149psf_log_SF_INFO (SF_PRIVATE *psf)
1150{ psf_log_printf (psf, "---------------------------------\n") ;
1151
1152 psf_log_printf (psf, " Sample rate : %d\n", psf->sf.samplerate) ;
1153 psf_log_printf (psf, " Frames : %D\n", psf->sf.frames) ;
1154 psf_log_printf (psf, " Channels : %d\n", psf->sf.channels) ;
1155
1156 psf_log_printf (psf, " Format : 0x%X\n", psf->sf.format) ;
1157 psf_log_printf (psf, " Sections : %d\n", psf->sf.sections) ;
1158 psf_log_printf (psf, " Seekable : %s\n", psf->sf.seekable ? "TRUE" : "FALSE") ;
1159
1160 psf_log_printf (psf, "---------------------------------\n") ;
1161} /* psf_dump_SFINFO */
1162
1163/*========================================================================================
1164*/
1165
1166void*
1167psf_memset (void *s, int c, sf_count_t len)
1168{ char *ptr ;
1169 int setcount ;
1170
1171 ptr = (char *) s ;
1172
1173 while (len > 0)
1174 { setcount = (len > 0x10000000) ? 0x10000000 : (int) len ;
1175
1176 memset (ptr, c, setcount) ;
1177
1178 ptr += setcount ;
1179 len -= setcount ;
1180 } ;
1181
1182 return s ;
1183} /* psf_memset */
1184
1185SF_INSTRUMENT *
1186psf_instrument_alloc (void)
1187{ SF_INSTRUMENT *instr ;
1188
1189 instr = calloc (1, sizeof (SF_INSTRUMENT)) ;
1190
1191 if (instr == NULL)
1192 return NULL ;
1193
1194 /* Set non-zero default values. */
1195 instr->basenote = -1 ;
1196 instr->velocity_lo = -1 ;
1197 instr->velocity_hi = -1 ;
1198 instr->key_lo = -1 ;
1199 instr->key_hi = -1 ;
1200
1201 return instr ;
1202} /* psf_instrument_alloc */
1203
1204void
1205psf_sanitize_string (char * cptr, int len)
1206{
1207 do
1208 {
1209 len -- ;
1210 cptr [len] = psf_isprint (cptr [len]) ? cptr [len] : '.' ;
1211 }
1212 while (len > 0) ;
1213} /* psf_sanitize_string */
1214
1215void
1216psf_get_date_str (char *str, int maxlen)
1217{ time_t current ;
1218 struct tm timedata, *tmptr ;
1219
1220 time (&current) ;
1221
1222#if defined (HAVE_GMTIME_R)
1223 /* If the re-entrant version is available, use it. */
1224 tmptr = gmtime_r (&current, &timedata) ;
1225#elif defined (HAVE_GMTIME)
1226 /* Otherwise use the standard one and copy the data to local storage. */
1227 tmptr = gmtime (&current) ;
1228 memcpy (&timedata, tmptr, sizeof (timedata)) ;
1229#else
1230 tmptr = NULL ;
1231#endif
1232
1233 if (tmptr)
1234 snprintf (str, maxlen, "%4d-%02d-%02d %02d:%02d:%02d UTC",
1235 1900 + timedata.tm_year, timedata.tm_mon, timedata.tm_mday,
1236 timedata.tm_hour, timedata.tm_min, timedata.tm_sec) ;
1237 else
1238 snprintf (str, maxlen, "Unknown date") ;
1239
1240 return ;
1241} /* psf_get_date_str */
1242
1243int
1244subformat_to_bytewidth (int format)
1245{
1246 switch (format)
1247 { case SF_FORMAT_PCM_U8 :
1248 case SF_FORMAT_PCM_S8 :
1249 return 1 ;
1250 case SF_FORMAT_PCM_16 :
1251 return 2 ;
1252 case SF_FORMAT_PCM_24 :
1253 return 3 ;
1254 case SF_FORMAT_PCM_32 :
1255 case SF_FORMAT_FLOAT :
1256 return 4 ;
1257 case SF_FORMAT_DOUBLE :
1258 return 8 ;
1259 } ;
1260
1261 return 0 ;
1262} /* subformat_to_bytewidth */
1263
1264int
1265s_bitwidth_to_subformat (int bits)
1266{ static int array [] =
1267 { SF_FORMAT_PCM_S8, SF_FORMAT_PCM_16, SF_FORMAT_PCM_24, SF_FORMAT_PCM_32
1268 } ;
1269
1270 if (bits < 8 || bits > 32)
1271 return 0 ;
1272
1273 return array [((bits + 7) / 8) - 1] ;
1274} /* bitwidth_to_subformat */
1275
1276int
1277u_bitwidth_to_subformat (int bits)
1278{ static int array [] =
1279 { SF_FORMAT_PCM_U8, SF_FORMAT_PCM_16, SF_FORMAT_PCM_24, SF_FORMAT_PCM_32
1280 } ;
1281
1282 if (bits < 8 || bits > 32)
1283 return 0 ;
1284
1285 return array [((bits + 7) / 8) - 1] ;
1286} /* bitwidth_to_subformat */
1287
1288/*
1289** psf_rand_int32 : Not crypto quality, but more than adequate for things
1290** like stream serial numbers in Ogg files or the unique_id field of the
1291** SF_PRIVATE struct.
1292*/
1293
1294int32_t
1295psf_rand_int32 (void)
1296{ static int32_t value = -1 ;
1297 int k, count ;
1298
1299 if (value == -1)
1300 {
1301#if HAVE_GETTIMEOFDAY
1302 struct timeval tv ;
1303 gettimeofday (&tv, NULL) ;
1304 value = tv.tv_sec + tv.tv_usec ;
1305#else
1306 value = time (NULL) ;
1307#endif
1308 } ;
1309
1310 count = 4 + (value & 7) ;
1311 for (k = 0 ; k < count ; k++)
1312 value = 11117 * value + 211231 ;
1313
1314 return value ;
1315} /* psf_rand_int32 */
1316
1317void
1318append_snprintf (char * dest, size_t maxlen, const char * fmt, ...)
1319{ size_t len = strlen (dest) ;
1320
1321 if (len < maxlen)
1322 { va_list ap ;
1323
1324 va_start (ap, fmt) ;
1325 vsnprintf (dest + len, maxlen - len, fmt, ap) ;
1326 va_end (ap) ;
1327 } ;
1328
1329 return ;
1330} /* append_snprintf */
1331
1332
1333void
1334psf_strlcpy_crlf (char *dest, const char *src, size_t destmax, size_t srcmax)
1335{ /* Must be minus 2 so it can still expand a single trailing '\n' or '\r'. */
1336 char * destend = dest + destmax - 2 ;
1337 const char * srcend = src + srcmax ;
1338
1339 while (dest < destend && src < srcend)
1340 { if ((src [0] == '\r' && src [1] == '\n') || (src [0] == '\n' && src [1] == '\r'))
1341 { *dest++ = '\r' ;
1342 *dest++ = '\n' ;
1343 src += 2 ;
1344 continue ;
1345 } ;
1346
1347 if (src [0] == '\r')
1348 { *dest++ = '\r' ;
1349 *dest++ = '\n' ;
1350 src += 1 ;
1351 continue ;
1352 } ;
1353
1354 if (src [0] == '\n')
1355 { *dest++ = '\r' ;
1356 *dest++ = '\n' ;
1357 src += 1 ;
1358 continue ;
1359 } ;
1360
1361 *dest++ = *src++ ;
1362 } ;
1363
1364 /* Make sure dest is terminated. */
1365 *dest = 0 ;
1366} /* psf_strlcpy_crlf */
1367
1368/*==============================================================================
1369*/
1370
1371#define CASE_NAME(x) case x : return #x ; break ;
1372
1373const char *
1374str_of_major_format (int format)
1375{ switch (SF_CONTAINER (format))
1376 { CASE_NAME (SF_FORMAT_WAV) ;
1377 CASE_NAME (SF_FORMAT_AIFF) ;
1378 CASE_NAME (SF_FORMAT_AU) ;
1379 CASE_NAME (SF_FORMAT_RAW) ;
1380 CASE_NAME (SF_FORMAT_PAF) ;
1381 CASE_NAME (SF_FORMAT_SVX) ;
1382 CASE_NAME (SF_FORMAT_NIST) ;
1383 CASE_NAME (SF_FORMAT_VOC) ;
1384 CASE_NAME (SF_FORMAT_IRCAM) ;
1385 CASE_NAME (SF_FORMAT_W64) ;
1386 CASE_NAME (SF_FORMAT_MAT4) ;
1387 CASE_NAME (SF_FORMAT_MAT5) ;
1388 CASE_NAME (SF_FORMAT_PVF) ;
1389 CASE_NAME (SF_FORMAT_XI) ;
1390 CASE_NAME (SF_FORMAT_HTK) ;
1391 CASE_NAME (SF_FORMAT_SDS) ;
1392 CASE_NAME (SF_FORMAT_AVR) ;
1393 CASE_NAME (SF_FORMAT_WAVEX) ;
1394 CASE_NAME (SF_FORMAT_SD2) ;
1395 CASE_NAME (SF_FORMAT_FLAC) ;
1396 CASE_NAME (SF_FORMAT_CAF) ;
1397 CASE_NAME (SF_FORMAT_WVE) ;
1398 CASE_NAME (SF_FORMAT_OGG) ;
1399 default :
1400 break ;
1401 } ;
1402
1403 return "BAD_MAJOR_FORMAT" ;
1404} /* str_of_major_format */
1405
1406const char *
1407str_of_minor_format (int format)
1408{ switch (SF_CODEC (format))
1409 { CASE_NAME (SF_FORMAT_PCM_S8) ;
1410 CASE_NAME (SF_FORMAT_PCM_16) ;
1411 CASE_NAME (SF_FORMAT_PCM_24) ;
1412 CASE_NAME (SF_FORMAT_PCM_32) ;
1413 CASE_NAME (SF_FORMAT_PCM_U8) ;
1414 CASE_NAME (SF_FORMAT_FLOAT) ;
1415 CASE_NAME (SF_FORMAT_DOUBLE) ;
1416 CASE_NAME (SF_FORMAT_ULAW) ;
1417 CASE_NAME (SF_FORMAT_ALAW) ;
1418 CASE_NAME (SF_FORMAT_IMA_ADPCM) ;
1419 CASE_NAME (SF_FORMAT_MS_ADPCM) ;
1420 CASE_NAME (SF_FORMAT_GSM610) ;
1421 CASE_NAME (SF_FORMAT_VOX_ADPCM) ;
1422 CASE_NAME (SF_FORMAT_G721_32) ;
1423 CASE_NAME (SF_FORMAT_G723_24) ;
1424 CASE_NAME (SF_FORMAT_G723_40) ;
1425 CASE_NAME (SF_FORMAT_DWVW_12) ;
1426 CASE_NAME (SF_FORMAT_DWVW_16) ;
1427 CASE_NAME (SF_FORMAT_DWVW_24) ;
1428 CASE_NAME (SF_FORMAT_DWVW_N) ;
1429 CASE_NAME (SF_FORMAT_DPCM_8) ;
1430 CASE_NAME (SF_FORMAT_DPCM_16) ;
1431 CASE_NAME (SF_FORMAT_VORBIS) ;
1432 default :
1433 break ;
1434 } ;
1435
1436 return "BAD_MINOR_FORMAT" ;
1437} /* str_of_minor_format */
1438
1439const char *
1440str_of_open_mode (int mode)
1441{ switch (mode)
1442 { CASE_NAME (SFM_READ) ;
1443 CASE_NAME (SFM_WRITE) ;
1444 CASE_NAME (SFM_RDWR) ;
1445
1446 default :
1447 break ;
1448 } ;
1449
1450 return "BAD_MODE" ;
1451} /* str_of_open_mode */
1452
1453const char *
1454str_of_endianness (int end)
1455{ switch (end)
1456 { CASE_NAME (SF_ENDIAN_BIG) ;
1457 CASE_NAME (SF_ENDIAN_LITTLE) ;
1458 CASE_NAME (SF_ENDIAN_CPU) ;
1459 default :
1460 break ;
1461 } ;
1462
1463 /* Zero length string for SF_ENDIAN_FILE. */
1464 return "" ;
1465} /* str_of_endianness */