2 ** Copyright (C) 1999-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
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.
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.
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.
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
42 log_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 ;
51 psf_log_printf (SF_PRIVATE
*psf
, const char *format
, ...)
54 int d
, tens
, shift
, width
, width_specifier
, left_align
;
55 char c
, *strptr
, istr
[5], lead_char
, sign_char
;
57 va_start (ap
, format
) ;
59 while ((c
= *format
++))
61 { log_putchar (psf
, c
) ;
65 if (format
[0] == '%') /* Handle %% */
66 { log_putchar (psf
, '%') ;
72 left_align
= SF_FALSE
;
77 sign_char
= format
[0] ;
82 left_align
= SF_TRUE
;
96 if (format
[0] == '0')
100 while ((c
= *format
++) && isdigit (c
))
101 width_specifier
= width_specifier
* 10 + (c
- '0') ;
104 { case 0 : /* NULL character. */
108 case 's': /* string */
109 strptr
= va_arg (ap
, char *) ;
112 width_specifier
-= strlen (strptr
) ;
113 if (left_align
== SF_FALSE
)
114 while (width_specifier
-- > 0)
115 log_putchar (psf
, ' ') ;
117 log_putchar (psf
, *strptr
++) ;
118 while (width_specifier
-- > 0)
119 log_putchar (psf
, ' ') ;
123 d
= va_arg (ap
, int) ;
128 if (lead_char
!= '0' && left_align
== SF_FALSE
)
134 while (d
/ tens
>= 10)
139 width_specifier
-= width
;
141 if (sign_char
== ' ')
142 { log_putchar (psf
, ' ') ;
146 if (left_align
== SF_FALSE
&& lead_char
!= '0')
147 { if (sign_char
== '+')
150 while (width_specifier
-- > 0)
151 log_putchar (psf
, lead_char
) ;
154 if (sign_char
== '+' || sign_char
== '-')
155 { log_putchar (psf
, sign_char
) ;
159 if (left_align
== SF_FALSE
)
160 while (width_specifier
-- > 0)
161 log_putchar (psf
, lead_char
) ;
164 { log_putchar (psf
, '0' + d
/ tens
) ;
169 while (width_specifier
-- > 0)
170 log_putchar (psf
, lead_char
) ;
173 case 'D': /* sf_count_t */
174 { sf_count_t D
, Tens
;
176 D
= va_arg (ap
, sf_count_t
) ;
179 { while (-- width_specifier
> 0)
180 log_putchar (psf
, lead_char
) ;
181 log_putchar (psf
, '0') ;
185 { log_putchar (psf
, '-') ;
190 while (D
/ Tens
>= 10)
195 while (width_specifier
> width
)
196 { log_putchar (psf
, lead_char
) ;
201 { log_putchar (psf
, '0' + D
/ Tens
) ;
208 case 'u': /* unsigned int */
209 u
= va_arg (ap
, unsigned int) ;
213 while (u
/ tens
>= 10)
218 width_specifier
-= width
;
220 if (sign_char
== ' ')
221 { log_putchar (psf
, ' ') ;
225 if (left_align
== SF_FALSE
&& lead_char
!= '0')
226 { if (sign_char
== '+')
229 while (width_specifier
-- > 0)
230 log_putchar (psf
, lead_char
) ;
233 if (sign_char
== '+' || sign_char
== '-')
234 { log_putchar (psf
, sign_char
) ;
238 if (left_align
== SF_FALSE
)
239 while (width_specifier
-- > 0)
240 log_putchar (psf
, lead_char
) ;
243 { log_putchar (psf
, '0' + u
/ tens
) ;
248 while (width_specifier
-- > 0)
249 log_putchar (psf
, lead_char
) ;
253 c
= va_arg (ap
, int) & 0xFF ;
254 log_putchar (psf
, c
) ;
259 d
= va_arg (ap
, int) ;
262 { while (--width_specifier
> 0)
263 log_putchar (psf
, lead_char
) ;
264 log_putchar (psf
, '0') ;
268 width
= (width_specifier
< 8) ? 8 : width_specifier
;
269 while (! ((0xF << shift
) & d
))
274 while (width
> 0 && width_specifier
> width
)
275 { log_putchar (psf
, lead_char
) ;
280 { c
= (d
>> shift
) & 0xF ;
281 log_putchar (psf
, (c
> 9) ? c
+ 'A' - 10 : c
+ '0') ;
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 ;
295 { istr
[3] = d
& 0xFF ;
296 istr
[2] = (d
>> 8) & 0xFF ;
297 istr
[1] = (d
>> 16) & 0xFF ;
298 istr
[0] = (d
>> 24) & 0xFF ;
304 log_putchar (psf
, c
) ;
309 log_putchar (psf
, '*') ;
310 log_putchar (psf
, c
) ;
311 log_putchar (psf
, '*') ;
318 } /* psf_log_printf */
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.
329 psf_asciiheader_printf (SF_PRIVATE
*psf
, const char *format
, ...)
334 maxlen
= strlen ((char*) psf
->header
) ;
335 start
= ((char*) psf
->header
) + maxlen
;
336 maxlen
= sizeof (psf
->header
) - maxlen
;
338 va_start (argptr
, format
) ;
339 vsnprintf (start
, maxlen
, format
, argptr
) ;
342 /* Make sure the string is properly terminated. */
343 start
[maxlen
- 1] = 0 ;
345 psf
->headindex
= strlen ((char*) psf
->header
) ;
348 } /* psf_asciiheader_printf */
350 /*-----------------------------------------------------------------------------------------------
351 ** Binary header writing functions. Returns number of bytes written.
353 ** Format specifiers for psf_binheader_writef are as follows
354 ** m - marker - four bytes - no endian manipulation
356 ** e - all following numerical values will be little endian
357 ** E - all following numerical values will be big endian
359 ** t - all following O types will be truncated to 4 bytes
360 ** T - switch off truncation of all following O types
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)
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
374 ** b - binary data (see below)
375 ** z - zero bytes (ses below)
376 ** j - jump forwards or backwards
378 ** To write a word followed by an int (both little endian) use:
379 ** psf_binheader_writef ("e24", wordval, longval) ;
381 ** To write binary data use:
382 ** psf_binheader_writef ("b", &bindata, sizeof (bindata)) ;
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) ;
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.
395 header_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 */
400 #if (CPU_IS_BIG_ENDIAN == 1)
402 header_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
;
409 } /* header_put_marker */
411 #elif (CPU_IS_LITTLE_ENDIAN == 1)
413 header_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) ;
420 } /* header_put_marker */
423 # error "Cannot determine endian-ness of processor."
428 header_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
;
433 } /* header_put_be_short */
436 header_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) ;
441 } /* header_put_le_short */
444 header_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
;
450 } /* header_put_be_3byte */
453 header_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) ;
459 } /* header_put_le_3byte */
462 header_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
;
469 } /* header_put_be_int */
472 header_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) ;
479 } /* header_put_le_int */
481 #if (SIZEOF_SF_COUNT_T == 4)
484 header_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
;
495 } /* header_put_be_8byte */
498 header_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 ;
509 } /* header_put_le_8byte */
511 #elif (SIZEOF_SF_COUNT_T == 8)
514 header_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
;
525 } /* header_put_be_8byte */
528 header_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) ;
539 } /* header_put_le_8byte */
542 #error "SIZEOF_SF_COUNT_T is not defined."
546 psf_binheader_writef (SF_PRIVATE
*psf
, const char *format
, ...)
548 sf_count_t countdata
;
549 unsigned long longdata
;
556 int count
= 0, trunc_8to4
;
558 trunc_8to4
= SF_FALSE
;
560 va_start (argptr
, format
) ;
562 while ((c
= *format
++))
564 { case ' ' : /* Do nothing. Just used to space out format string. */
567 case 'e' : /* All conversions are now from LE to host. */
568 psf
->rwf_endian
= SF_ENDIAN_LITTLE
;
571 case 'E' : /* All conversions are now from BE to host. */
572 psf
->rwf_endian
= SF_ENDIAN_BIG
;
575 case 't' : /* All 8 byte values now get written as 4 bytes. */
576 trunc_8to4
= SF_TRUE
;
579 case 'T' : /* All 8 byte values now get written as 8 bytes. */
580 trunc_8to4
= SF_FALSE
;
584 data
= va_arg (argptr
, unsigned int) ;
585 header_put_marker (psf
, data
) ;
590 data
= va_arg (argptr
, unsigned int) ;
591 header_put_byte (psf
, data
) ;
596 data
= va_arg (argptr
, unsigned int) ;
597 if (psf
->rwf_endian
== SF_ENDIAN_BIG
)
598 { header_put_be_short (psf
, data
) ;
601 { header_put_le_short (psf
, data
) ;
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
) ;
612 { header_put_le_3byte (psf
, data
) ;
618 data
= va_arg (argptr
, unsigned int) ;
619 if (psf
->rwf_endian
== SF_ENDIAN_BIG
)
620 { header_put_be_int (psf
, data
) ;
623 { header_put_le_int (psf
, data
) ;
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
) ;
634 else if (psf
->rwf_endian
== SF_ENDIAN_LITTLE
&& trunc_8to4
== SF_FALSE
)
635 { header_put_le_8byte (psf
, countdata
) ;
638 else if (psf
->rwf_endian
== SF_ENDIAN_BIG
&& trunc_8to4
== SF_TRUE
)
639 { longdata
= countdata
& 0xFFFFFFFF ;
640 header_put_be_int (psf
, longdata
) ;
643 else if (psf
->rwf_endian
== SF_ENDIAN_LITTLE
&& trunc_8to4
== SF_TRUE
)
644 { longdata
= countdata
& 0xFFFFFFFF ;
645 header_put_le_int (psf
, longdata
) ;
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
) ;
656 float32_le_write (floatdata
, psf
->header
+ psf
->headindex
) ;
657 psf
->headindex
+= 4 ;
662 doubledata
= va_arg (argptr
, double) ;
663 if (psf
->rwf_endian
== SF_ENDIAN_BIG
)
664 double64_be_write (doubledata
, psf
->header
+ psf
->headindex
) ;
666 double64_le_write (doubledata
, psf
->header
+ psf
->headindex
) ;
667 psf
->headindex
+= 8 ;
672 /* Write a C string (guaranteed to have a zero terminator). */
673 strptr
= va_arg (argptr
, char *) ;
674 size
= strlen (strptr
) + 1 ;
676 if (psf
->rwf_endian
== SF_ENDIAN_BIG
)
677 header_put_be_int (psf
, size
) ;
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 ;
688 ** Write an AIFF style string (no zero terminator but possibly
689 ** an extra pad byte if the string length is odd).
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
) ;
696 header_put_le_int (psf
, size
) ;
697 memcpy (&(psf
->header
[psf
->headindex
]), strptr
, size
+ 1) ;
699 psf
->headindex
+= size
;
700 psf
->header
[psf
->headindex
] = 0 ;
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
;
713 size
= va_arg (argptr
, size_t) ;
716 { psf
->header
[psf
->headindex
] = 0 ;
723 bindata
= va_arg (argptr
, void *) ;
724 memcpy (&(psf
->header
[psf
->headindex
]), bindata
, 16) ;
725 psf
->headindex
+= 16 ;
730 size
= va_arg (argptr
, size_t) ;
731 psf
->headindex
+= size
;
736 psf_log_printf (psf
, "*** Invalid format specifier `%c'\n", c
) ;
737 psf
->error
= SFE_INTERNAL
;
744 } /* psf_binheader_writef */
746 /*-----------------------------------------------------------------------------------------------
747 ** Binary header reading functions. Returns number of bytes read.
749 ** Format specifiers are the same as for header write function above with the following
752 ** p - jump a given number of position from start of file.
754 ** If format is NULL, psf_binheader_readf returns the current offset.
757 #if (CPU_IS_BIG_ENDIAN == 1)
758 #define GET_MARKER(ptr) ( ((ptr) [0] << 24) | ((ptr) [1] << 16) | \
759 ((ptr) [2] << 8) | ((ptr) [3]) )
761 #elif (CPU_IS_LITTLE_ENDIAN == 1)
762 #define GET_MARKER(ptr) ( ((ptr) [0]) | ((ptr) [1] << 8) | \
763 ((ptr) [2] << 16) | ((ptr) [3] << 24) )
766 # error "Cannot determine endian-ness of processor."
769 #define GET_LE_SHORT(ptr) ( ((ptr) [1] << 8) | ((ptr) [0]) )
770 #define GET_BE_SHORT(ptr) ( ((ptr) [0] << 8) | ((ptr) [1]) )
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]) )
775 #define GET_LE_INT(ptr) ( ((ptr) [3] << 24) | ((ptr) [2] << 16) | \
776 ((ptr) [1] << 8) | ((ptr) [0]) )
778 #define GET_BE_INT(ptr) ( ((ptr) [0] << 24) | ((ptr) [1] << 16) | \
779 ((ptr) [2] << 8) | ((ptr) [3]) )
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]))
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]))
794 header_read (SF_PRIVATE
*psf
, void *ptr
, int bytes
)
797 if (psf
->headindex
>= SIGNED_SIZEOF (psf
->header
))
798 { memset (ptr
, 0, SIGNED_SIZEOF (psf
->header
) - psf
->headindex
) ;
800 /* This is the best that we can do. */
801 psf_fseek (psf
, bytes
, SEEK_CUR
) ;
805 if (psf
->headindex
+ bytes
> SIGNED_SIZEOF (psf
->header
))
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
) ;
812 psf_fseek (psf
, bytes
- most
, SEEK_CUR
) ;
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") ;
822 psf
->headend
+= count
;
825 memcpy (ptr
, psf
->header
+ psf
->headindex
, bytes
) ;
826 psf
->headindex
+= bytes
;
832 header_seek (SF_PRIVATE
*psf
, sf_count_t position
, int whence
)
837 if (position
> SIGNED_SIZEOF (psf
->header
))
838 { /* Too much header to cache so just seek instead. */
839 psf_fseek (psf
, position
, whence
) ;
842 if (position
> psf
->headend
)
843 psf
->headend
+= psf_fread (psf
->header
+ psf
->headend
, 1, position
- psf
->headend
, psf
) ;
844 psf
->headindex
= position
;
848 if (psf
->headindex
+ position
< 0)
851 if (psf
->headindex
>= SIGNED_SIZEOF (psf
->header
))
852 { psf_fseek (psf
, position
, whence
) ;
856 if (psf
->headindex
+ position
<= psf
->headend
)
857 { psf
->headindex
+= position
;
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
) ;
868 psf
->headend
+= psf_fread (psf
->header
+ psf
->headend
, 1, position
- (psf
->headend
- psf
->headindex
), psf
) ;
869 psf
->headindex
= psf
->headend
;
874 psf_log_printf (psf
, "Bad whence param in header_seek().\n") ;
882 header_gets (SF_PRIVATE
*psf
, char *ptr
, int bufsize
)
886 for (k
= 0 ; k
< bufsize
- 1 ; k
++)
887 { if (psf
->headindex
< psf
->headend
)
888 { ptr
[k
] = psf
->header
[psf
->headindex
] ;
892 { psf
->headend
+= psf_fread (psf
->header
+ psf
->headend
, 1, 1, psf
) ;
893 ptr
[k
] = psf
->header
[psf
->headindex
] ;
894 psf
->headindex
= psf
->headend
;
907 psf_binheader_readf (SF_PRIVATE
*psf
, char const *format
, ...)
909 sf_count_t
*countptr
, countdata
;
910 unsigned char *ucptr
, sixteen_bytes
[16] ;
911 unsigned int *intptr
, intdata
;
912 unsigned short *shortptr
;
917 int byte_count
= 0, count
;
920 return psf_ftell (psf
) ;
922 va_start (argptr
, format
) ;
924 while ((c
= *format
++))
926 { case 'e' : /* All conversions are now from LE to host. */
927 psf
->rwf_endian
= SF_ENDIAN_LITTLE
;
930 case 'E' : /* All conversions are now from BE to host. */
931 psf
->rwf_endian
= SF_ENDIAN_BIG
;
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
) ;
942 intptr
= va_arg (argptr
, unsigned int*) ;
943 ucptr
= (unsigned char*) intptr
;
944 byte_count
+= header_read (psf
, sixteen_bytes
, sizeof (sixteen_bytes
)) ;
947 for (k
= 0 ; k
< 16 ; k
++)
948 intdata
^= sixteen_bytes
[k
] << k
;
954 charptr
= va_arg (argptr
, char*) ;
956 byte_count
+= header_read (psf
, charptr
, sizeof (char)) ;
960 shortptr
= va_arg (argptr
, unsigned short*) ;
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
) ;
967 *shortptr
= GET_LE_SHORT (ucptr
) ;
971 intptr
= va_arg (argptr
, unsigned int*) ;
973 byte_count
+= header_read (psf
, sixteen_bytes
, 3) ;
974 if (psf
->rwf_endian
== SF_ENDIAN_BIG
)
975 *intptr
= GET_BE_3BYTE (sixteen_bytes
) ;
977 *intptr
= GET_LE_3BYTE (sixteen_bytes
) ;
981 intptr
= va_arg (argptr
, unsigned int*) ;
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
) ;
988 *intptr
= GET_LE_INT (ucptr
) ;
992 countptr
= va_arg (argptr
, sf_count_t
*) ;
994 byte_count
+= header_read (psf
, sixteen_bytes
, 8) ;
995 if (psf
->rwf_endian
== SF_ENDIAN_BIG
)
996 countdata
= GET_BE_8BYTE (sixteen_bytes
) ;
998 countdata
= GET_LE_8BYTE (sixteen_bytes
) ;
999 *countptr
= countdata
;
1002 case 'f' : /* Float conversion */
1003 floatptr
= va_arg (argptr
, float *) ;
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
) ;
1009 *floatptr
= float32_le_read ((unsigned char*) floatptr
) ;
1012 case 'd' : /* double conversion */
1013 doubleptr
= va_arg (argptr
, double *) ;
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
) ;
1019 *doubleptr
= double64_le_read ((unsigned char*) doubleptr
) ;
1023 psf_log_printf (psf
, "Format conversion 's' not implemented yet.\n") ;
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 ;
1036 charptr
= va_arg (argptr
, char*) ;
1037 count
= va_arg (argptr
, size_t) ;
1039 byte_count
+= header_read (psf
, charptr
, count
) ;
1043 charptr
= va_arg (argptr
, char*) ;
1044 count
= va_arg (argptr
, size_t) ;
1046 byte_count
+= header_gets (psf
, charptr
, count
) ;
1050 psf_log_printf (psf
, "Format conversion 'z' not implemented yet.\n") ;
1052 size = va_arg (argptr, size_t) ;
1054 { psf->header [psf->headindex] = 0 ;
1062 /* Get the seek position first. */
1063 count
= va_arg (argptr
, size_t) ;
1064 header_seek (psf
, count
, SEEK_SET
) ;
1065 byte_count
= count
;
1069 /* Get the seek position first. */
1070 count
= va_arg (argptr
, size_t) ;
1071 header_seek (psf
, count
, SEEK_CUR
) ;
1072 byte_count
+= count
;
1076 psf_log_printf (psf
, "*** Invalid format specifier `%c'\n", c
) ;
1077 psf
->error
= SFE_INTERNAL
;
1085 } /* psf_binheader_readf */
1087 /*-----------------------------------------------------------------------------------------------
1091 psf_default_seek (SF_PRIVATE
*psf
, int UNUSED (mode
), sf_count_t samples_from_start
)
1092 { sf_count_t position
, retval
;
1094 if (! (psf
->blockwidth
&& psf
->dataoffset
>= 0))
1095 { psf
->error
= SFE_BAD_SEEK
;
1096 return PSF_SEEK_ERROR
;
1099 if (! psf
->sf
.seekable
)
1100 { psf
->error
= SFE_NOT_SEEKABLE
;
1101 return PSF_SEEK_ERROR
;
1104 position
= psf
->dataoffset
+ psf
->blockwidth
* samples_from_start
;
1106 if ((retval
= psf_fseek (psf
, position
, SEEK_SET
)) != position
)
1107 { psf
->error
= SFE_SEEK_FAILED
;
1108 return PSF_SEEK_ERROR
;
1111 return samples_from_start
;
1112 } /* psf_default_seek */
1114 /*-----------------------------------------------------------------------------------------------
1118 psf_hexdump (const void *ptr
, int len
)
1119 { const char *data
;
1123 if ((data
= ptr
) == NULL
)
1129 for (k
= 0 ; k
< len
; k
+= 16)
1130 { memset (ascii
, ' ', sizeof (ascii
)) ;
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
] : '.' ;
1138 if (m
<= 8) printf (" ") ;
1139 for ( ; m
< 16 ; m
++) printf (" ") ;
1142 printf (" %s\n", ascii
) ;
1149 psf_log_SF_INFO (SF_PRIVATE
*psf
)
1150 { psf_log_printf (psf
, "---------------------------------\n") ;
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
) ;
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") ;
1160 psf_log_printf (psf
, "---------------------------------\n") ;
1161 } /* psf_dump_SFINFO */
1163 /*========================================================================================
1167 psf_memset (void *s
, int c
, sf_count_t len
)
1174 { setcount
= (len
> 0x10000000) ? 0x10000000 : (int) len
;
1176 memset (ptr
, c
, setcount
) ;
1186 psf_instrument_alloc (void)
1187 { SF_INSTRUMENT
*instr
;
1189 instr
= calloc (1, sizeof (SF_INSTRUMENT
)) ;
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 ;
1202 } /* psf_instrument_alloc */
1205 psf_sanitize_string (char * cptr
, int len
)
1210 cptr
[len
] = psf_isprint (cptr
[len
]) ? cptr
[len
] : '.' ;
1213 } /* psf_sanitize_string */
1216 psf_get_date_str (char *str
, int maxlen
)
1218 struct tm timedata
, *tmptr
;
1222 #if defined (HAVE_GMTIME_R)
1223 /* If the re-entrant version is available, use it. */
1224 tmptr
= gmtime_r (¤t
, &timedata
) ;
1225 #elif defined (HAVE_GMTIME)
1226 /* Otherwise use the standard one and copy the data to local storage. */
1227 tmptr
= gmtime (¤t
) ;
1228 memcpy (&timedata
, tmptr
, sizeof (timedata
)) ;
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
) ;
1238 snprintf (str
, maxlen
, "Unknown date") ;
1241 } /* psf_get_date_str */
1244 subformat_to_bytewidth (int format
)
1247 { case SF_FORMAT_PCM_U8
:
1248 case SF_FORMAT_PCM_S8
:
1250 case SF_FORMAT_PCM_16
:
1252 case SF_FORMAT_PCM_24
:
1254 case SF_FORMAT_PCM_32
:
1255 case SF_FORMAT_FLOAT
:
1257 case SF_FORMAT_DOUBLE
:
1262 } /* subformat_to_bytewidth */
1265 s_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
1270 if (bits
< 8 || bits
> 32)
1273 return array
[((bits
+ 7) / 8) - 1] ;
1274 } /* bitwidth_to_subformat */
1277 u_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
1282 if (bits
< 8 || bits
> 32)
1285 return array
[((bits
+ 7) / 8) - 1] ;
1286 } /* bitwidth_to_subformat */
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.
1295 psf_rand_int32 (void)
1296 { static int32_t value
= -1 ;
1301 #if HAVE_GETTIMEOFDAY
1303 gettimeofday (&tv
, NULL
) ;
1304 value
= tv
.tv_sec
+ tv
.tv_usec
;
1306 value
= time (NULL
) ;
1310 count
= 4 + (value
& 7) ;
1311 for (k
= 0 ; k
< count
; k
++)
1312 value
= 11117 * value
+ 211231 ;
1315 } /* psf_rand_int32 */
1318 append_snprintf (char * dest
, size_t maxlen
, const char * fmt
, ...)
1319 { size_t len
= strlen (dest
) ;
1324 va_start (ap
, fmt
) ;
1325 vsnprintf (dest
+ len
, maxlen
- len
, fmt
, ap
) ;
1330 } /* append_snprintf */
1334 psf_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
;
1339 while (dest
< destend
&& src
< srcend
)
1340 { if ((src
[0] == '\r' && src
[1] == '\n') || (src
[0] == '\n' && src
[1] == '\r'))
1347 if (src
[0] == '\r')
1354 if (src
[0] == '\n')
1364 /* Make sure dest is terminated. */
1366 } /* psf_strlcpy_crlf */
1368 /*==============================================================================
1371 #define CASE_NAME(x) case x : return #x ; break ;
1374 str_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
) ;
1403 return "BAD_MAJOR_FORMAT" ;
1404 } /* str_of_major_format */
1407 str_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
) ;
1436 return "BAD_MINOR_FORMAT" ;
1437 } /* str_of_minor_format */
1440 str_of_open_mode (int mode
)
1442 { CASE_NAME (SFM_READ
) ;
1443 CASE_NAME (SFM_WRITE
) ;
1444 CASE_NAME (SFM_RDWR
) ;
1451 } /* str_of_open_mode */
1454 str_of_endianness (int end
)
1456 { CASE_NAME (SF_ENDIAN_BIG
) ;
1457 CASE_NAME (SF_ENDIAN_LITTLE
) ;
1458 CASE_NAME (SF_ENDIAN_CPU
) ;
1463 /* Zero length string for SF_ENDIAN_FILE. */
1465 } /* str_of_endianness */