2 ** Copyright (C) 1999-2006 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.
29 /*-----------------------------------------------------------------------------------------------
30 ** psf_log_printf allows libsndfile internal functions to print to an internal logbuffer which
31 ** can later be displayed.
32 ** The format specifiers are as for printf but without the field width and other modifiers.
33 ** Printing is performed to the logbuffer char array of the SF_PRIVATE struct.
34 ** Printing is done in such a way as to guarantee that the log never overflows the end of the
39 log_putchar (SF_PRIVATE *psf, char ch)
40 { if (psf->logindex < SIGNED_SIZEOF (psf->logbuffer) - 1)
41 { psf->logbuffer [psf->logindex++] = ch ;
42 psf->logbuffer [psf->logindex] = 0 ;
48 psf_log_printf (SF_PRIVATE *psf, const char *format, ...)
51 int d, tens, shift, width, width_specifier, left_align ;
52 char c, *strptr, istr [5], lead_char, sign_char ;
54 va_start (ap, format) ;
56 while ((c = *format++))
58 { log_putchar (psf, c) ;
62 if (format [0] == '%') /* Handle %% */
63 { log_putchar (psf, '%') ;
69 left_align = SF_FALSE ;
74 sign_char = format [0] ;
79 left_align = SF_TRUE ;
93 if (format [0] == '0')
97 while ((c = *format++) && isdigit (c))
98 width_specifier = width_specifier * 10 + (c - '0') ;
101 { case 0 : /* NULL character. */
105 case 's': /* string */
106 strptr = va_arg (ap, char *) ;
109 width_specifier -= strlen (strptr) ;
110 if (left_align == SF_FALSE)
111 while (width_specifier -- > 0)
112 log_putchar (psf, ' ') ;
114 log_putchar (psf, *strptr++) ;
115 while (width_specifier -- > 0)
116 log_putchar (psf, ' ') ;
120 d = va_arg (ap, int) ;
125 if (lead_char != '0' && left_align == SF_FALSE)
131 while (d / tens >= 10)
136 width_specifier -= width ;
138 if (sign_char == ' ')
139 { log_putchar (psf, ' ') ;
143 if (left_align == SF_FALSE && lead_char != '0')
144 { if (sign_char == '+')
147 while (width_specifier -- > 0)
148 log_putchar (psf, lead_char) ;
151 if (sign_char == '+' || sign_char == '-')
152 { log_putchar (psf, sign_char) ;
156 if (left_align == SF_FALSE)
157 while (width_specifier -- > 0)
158 log_putchar (psf, lead_char) ;
161 { log_putchar (psf, '0' + d / tens) ;
166 while (width_specifier -- > 0)
167 log_putchar (psf, lead_char) ;
170 case 'D': /* sf_count_t */
171 { sf_count_t D, Tens ;
173 D = va_arg (ap, sf_count_t) ;
176 { while (-- width_specifier > 0)
177 log_putchar (psf, lead_char) ;
178 log_putchar (psf, '0') ;
182 { log_putchar (psf, '-') ;
187 while (D / Tens >= 10)
192 while (width_specifier > width)
193 { log_putchar (psf, lead_char) ;
198 { log_putchar (psf, '0' + D / Tens) ;
205 case 'u': /* unsigned int */
206 u = va_arg (ap, unsigned int) ;
210 while (u / tens >= 10)
215 width_specifier -= width ;
217 if (sign_char == ' ')
218 { log_putchar (psf, ' ') ;
222 if (left_align == SF_FALSE && lead_char != '0')
223 { if (sign_char == '+')
226 while (width_specifier -- > 0)
227 log_putchar (psf, lead_char) ;
230 if (sign_char == '+' || sign_char == '-')
231 { log_putchar (psf, sign_char) ;
235 if (left_align == SF_FALSE)
236 while (width_specifier -- > 0)
237 log_putchar (psf, lead_char) ;
240 { log_putchar (psf, '0' + u / tens) ;
245 while (width_specifier -- > 0)
246 log_putchar (psf, lead_char) ;
250 c = va_arg (ap, int) & 0xFF ;
251 log_putchar (psf, c) ;
256 d = va_arg (ap, int) ;
259 { while (--width_specifier > 0)
260 log_putchar (psf, lead_char) ;
261 log_putchar (psf, '0') ;
265 width = (width_specifier < 8) ? 8 : width_specifier ;
266 while (! ((0xF << shift) & d))
271 while (width > 0 && width_specifier > width)
272 { log_putchar (psf, lead_char) ;
277 { c = (d >> shift) & 0xF ;
278 log_putchar (psf, (c > 9) ? c + 'A' - 10 : c + '0') ;
283 case 'M': /* int2str */
284 d = va_arg (ap, int) ;
285 if (CPU_IS_LITTLE_ENDIAN)
286 { istr [0] = d & 0xFF ;
287 istr [1] = (d >> 8) & 0xFF ;
288 istr [2] = (d >> 16) & 0xFF ;
289 istr [3] = (d >> 24) & 0xFF ;
292 { istr [3] = d & 0xFF ;
293 istr [2] = (d >> 8) & 0xFF ;
294 istr [1] = (d >> 16) & 0xFF ;
295 istr [0] = (d >> 24) & 0xFF ;
301 log_putchar (psf, c) ;
306 log_putchar (psf, '*') ;
307 log_putchar (psf, c) ;
308 log_putchar (psf, '*') ;
315 } /* psf_log_printf */
317 #ifndef PSF_LOG_PRINTF_ONLY
318 /*-----------------------------------------------------------------------------------------------
319 ** ASCII header printf functions.
320 ** Some formats (ie NIST) use ascii text in their headers.
321 ** Format specifiers are the same as the standard printf specifiers (uses vsnprintf).
322 ** If this generates a compile error on any system, the author should be notified
323 ** so an alternative vsnprintf can be provided.
327 psf_asciiheader_printf (SF_PRIVATE *psf, const char *format, ...)
332 maxlen = strlen ((char*) psf->header) ;
333 start = ((char*) psf->header) + maxlen ;
334 maxlen = sizeof (psf->header) - maxlen ;
336 va_start (argptr, format) ;
337 LSF_VSNPRINTF (start, maxlen, format, argptr) ;
340 /* Make sure the string is properly terminated. */
341 start [maxlen - 1] = 0 ;
343 psf->headindex = strlen ((char*) psf->header) ;
346 } /* psf_asciiheader_printf */
348 /*-----------------------------------------------------------------------------------------------
349 ** Binary header writing functions. Returns number of bytes written.
351 ** Format specifiers for psf_binheader_writef are as follows
352 ** m - marker - four bytes - no endian manipulation
354 ** e - all following numerical values will be little endian
355 ** E - all following numerical values will be big endian
357 ** t - all following O types will be truncated to 4 bytes
358 ** T - switch off truncation of all following O types
360 ** 1 - single byte value
361 ** 2 - two byte value
362 ** 3 - three byte value
363 ** 4 - four byte value
364 ** 8 - eight byte value (sometimes written as 4 bytes)
366 ** s - string preceded by a four byte length
367 ** S - string including null terminator
368 ** f - floating point data
369 ** d - double precision floating point data
370 ** h - 16 binary bytes value
372 ** b - binary data (see below)
373 ** z - zero bytes (ses below)
374 ** j - jump forwards or backwards
376 ** To write a word followed by an int (both little endian) use:
377 ** psf_binheader_writef ("e24", wordval, longval) ;
379 ** To write binary data use:
380 ** psf_binheader_writef ("b", &bindata, sizeof (bindata)) ;
382 ** To write N zero bytes use:
383 ** NOTE: due to platform issues (ie x86-64) you should cast the
384 ** argument to size_t or ensure the variable type is size_t.
385 ** psf_binheader_writef ("z", N) ;
388 /* These macros may seem a bit messy but do prevent problems with processors which
389 ** seg. fault when asked to write an int or short to a non-int/short aligned address.
393 header_put_byte (SF_PRIVATE *psf, char x)
394 { if (psf->headindex < SIGNED_SIZEOF (psf->header) - 1)
395 psf->header [psf->headindex++] = x ;
396 } /* header_put_byte */
398 #if (CPU_IS_BIG_ENDIAN == 1)
400 header_put_marker (SF_PRIVATE *psf, int x)
401 { if (psf->headindex < SIGNED_SIZEOF (psf->header) - 4)
402 { psf->header [psf->headindex++] = (x >> 24) ;
403 psf->header [psf->headindex++] = (x >> 16) ;
404 psf->header [psf->headindex++] = (x >> 8) ;
405 psf->header [psf->headindex++] = x ;
407 } /* header_put_marker */
409 #elif (CPU_IS_LITTLE_ENDIAN == 1)
411 header_put_marker (SF_PRIVATE *psf, int x)
412 { if (psf->headindex < SIGNED_SIZEOF (psf->header) - 4)
413 { psf->header [psf->headindex++] = x ;
414 psf->header [psf->headindex++] = (x >> 8) ;
415 psf->header [psf->headindex++] = (x >> 16) ;
416 psf->header [psf->headindex++] = (x >> 24) ;
418 } /* header_put_marker */
421 # error "Cannot determine endian-ness of processor."
426 header_put_be_short (SF_PRIVATE *psf, int x)
427 { if (psf->headindex < SIGNED_SIZEOF (psf->header) - 2)
428 { psf->header [psf->headindex++] = (x >> 8) ;
429 psf->header [psf->headindex++] = x ;
431 } /* header_put_be_short */
434 header_put_le_short (SF_PRIVATE *psf, int x)
435 { if (psf->headindex < SIGNED_SIZEOF (psf->header) - 2)
436 { psf->header [psf->headindex++] = x ;
437 psf->header [psf->headindex++] = (x >> 8) ;
439 } /* header_put_le_short */
442 header_put_be_3byte (SF_PRIVATE *psf, int x)
443 { if (psf->headindex < SIGNED_SIZEOF (psf->header) - 3)
444 { psf->header [psf->headindex++] = (x >> 16) ;
445 psf->header [psf->headindex++] = (x >> 8) ;
446 psf->header [psf->headindex++] = x ;
448 } /* header_put_be_3byte */
451 header_put_le_3byte (SF_PRIVATE *psf, int x)
452 { if (psf->headindex < SIGNED_SIZEOF (psf->header) - 3)
453 { psf->header [psf->headindex++] = x ;
454 psf->header [psf->headindex++] = (x >> 8) ;
455 psf->header [psf->headindex++] = (x >> 16) ;
457 } /* header_put_le_3byte */
460 header_put_be_int (SF_PRIVATE *psf, int x)
461 { if (psf->headindex < SIGNED_SIZEOF (psf->header) - 4)
462 { psf->header [psf->headindex++] = (x >> 24) ;
463 psf->header [psf->headindex++] = (x >> 16) ;
464 psf->header [psf->headindex++] = (x >> 8) ;
465 psf->header [psf->headindex++] = x ;
467 } /* header_put_be_int */
470 header_put_le_int (SF_PRIVATE *psf, int x)
471 { if (psf->headindex < SIGNED_SIZEOF (psf->header) - 4)
472 { psf->header [psf->headindex++] = x ;
473 psf->header [psf->headindex++] = (x >> 8) ;
474 psf->header [psf->headindex++] = (x >> 16) ;
475 psf->header [psf->headindex++] = (x >> 24) ;
477 } /* header_put_le_int */
479 #if (SIZEOF_SF_COUNT_T == 4)
482 header_put_be_8byte (SF_PRIVATE *psf, sf_count_t x)
483 { if (psf->headindex < SIGNED_SIZEOF (psf->header) - 8)
484 { psf->header [psf->headindex++] = 0 ;
485 psf->header [psf->headindex++] = 0 ;
486 psf->header [psf->headindex++] = 0 ;
487 psf->header [psf->headindex++] = 0 ;
488 psf->header [psf->headindex++] = (x >> 24) ;
489 psf->header [psf->headindex++] = (x >> 16) ;
490 psf->header [psf->headindex++] = (x >> 8) ;
491 psf->header [psf->headindex++] = x ;
493 } /* header_put_be_8byte */
496 header_put_le_8byte (SF_PRIVATE *psf, sf_count_t x)
497 { if (psf->headindex < SIGNED_SIZEOF (psf->header) - 8)
498 { psf->header [psf->headindex++] = x ;
499 psf->header [psf->headindex++] = (x >> 8) ;
500 psf->header [psf->headindex++] = (x >> 16) ;
501 psf->header [psf->headindex++] = (x >> 24) ;
502 psf->header [psf->headindex++] = 0 ;
503 psf->header [psf->headindex++] = 0 ;
504 psf->header [psf->headindex++] = 0 ;
505 psf->header [psf->headindex++] = 0 ;
507 } /* header_put_le_8byte */
509 #elif (SIZEOF_SF_COUNT_T == 8)
512 header_put_be_8byte (SF_PRIVATE *psf, sf_count_t x)
513 { if (psf->headindex < SIGNED_SIZEOF (psf->header) - 8)
514 { psf->header [psf->headindex++] = (x >> 56) ;
515 psf->header [psf->headindex++] = (x >> 48) ;
516 psf->header [psf->headindex++] = (x >> 40) ;
517 psf->header [psf->headindex++] = (x >> 32) ;
518 psf->header [psf->headindex++] = (x >> 24) ;
519 psf->header [psf->headindex++] = (x >> 16) ;
520 psf->header [psf->headindex++] = (x >> 8) ;
521 psf->header [psf->headindex++] = x ;
523 } /* header_put_be_8byte */
526 header_put_le_8byte (SF_PRIVATE *psf, sf_count_t x)
527 { if (psf->headindex < SIGNED_SIZEOF (psf->header) - 8)
528 { psf->header [psf->headindex++] = x ;
529 psf->header [psf->headindex++] = (x >> 8) ;
530 psf->header [psf->headindex++] = (x >> 16) ;
531 psf->header [psf->headindex++] = (x >> 24) ;
532 psf->header [psf->headindex++] = (x >> 32) ;
533 psf->header [psf->headindex++] = (x >> 40) ;
534 psf->header [psf->headindex++] = (x >> 48) ;
535 psf->header [psf->headindex++] = (x >> 56) ;
537 } /* header_put_le_8byte */
540 #error "SIZEOF_SF_COUNT_T is not defined."
544 psf_binheader_writef (SF_PRIVATE *psf, const char *format, ...)
546 sf_count_t countdata ;
547 unsigned long longdata ;
554 int count = 0, trunc_8to4 ;
556 trunc_8to4 = SF_FALSE ;
558 va_start (argptr, format) ;
560 while ((c = *format++))
562 { case ' ' : /* Do nothing. Just used to space out format string. */
565 case 'e' : /* All conversions are now from LE to host. */
566 psf->rwf_endian = SF_ENDIAN_LITTLE ;
569 case 'E' : /* All conversions are now from BE to host. */
570 psf->rwf_endian = SF_ENDIAN_BIG ;
573 case 't' : /* All 8 byte values now get written as 4 bytes. */
574 trunc_8to4 = SF_TRUE ;
577 case 'T' : /* All 8 byte values now get written as 8 bytes. */
578 trunc_8to4 = SF_FALSE ;
582 data = va_arg (argptr, unsigned int) ;
583 header_put_marker (psf, data) ;
588 data = va_arg (argptr, unsigned int) ;
589 header_put_byte (psf, data) ;
594 data = va_arg (argptr, unsigned int) ;
595 if (psf->rwf_endian == SF_ENDIAN_BIG)
596 { header_put_be_short (psf, data) ;
599 { header_put_le_short (psf, data) ;
604 case '3' : /* tribyte */
605 data = va_arg (argptr, unsigned int) ;
606 if (psf->rwf_endian == SF_ENDIAN_BIG)
607 { header_put_be_3byte (psf, data) ;
610 { header_put_le_3byte (psf, data) ;
616 data = va_arg (argptr, unsigned int) ;
617 if (psf->rwf_endian == SF_ENDIAN_BIG)
618 { header_put_be_int (psf, data) ;
621 { header_put_le_int (psf, data) ;
627 countdata = va_arg (argptr, sf_count_t) ;
628 if (psf->rwf_endian == SF_ENDIAN_BIG && trunc_8to4 == SF_FALSE)
629 { header_put_be_8byte (psf, countdata) ;
632 else if (psf->rwf_endian == SF_ENDIAN_LITTLE && trunc_8to4 == SF_FALSE)
633 { header_put_le_8byte (psf, countdata) ;
636 else if (psf->rwf_endian == SF_ENDIAN_BIG && trunc_8to4 == SF_TRUE)
637 { longdata = countdata & 0xFFFFFFFF ;
638 header_put_be_int (psf, longdata) ;
641 else if (psf->rwf_endian == SF_ENDIAN_LITTLE && trunc_8to4 == SF_TRUE)
642 { longdata = countdata & 0xFFFFFFFF ;
643 header_put_le_int (psf, longdata) ;
649 /* Floats are passed as doubles. Is this always true? */
650 floatdata = (float) va_arg (argptr, double) ;
651 if (psf->rwf_endian == SF_ENDIAN_BIG)
652 float32_be_write (floatdata, psf->header + psf->headindex) ;
654 float32_le_write (floatdata, psf->header + psf->headindex) ;
655 psf->headindex += 4 ;
660 doubledata = va_arg (argptr, double) ;
661 if (psf->rwf_endian == SF_ENDIAN_BIG)
662 double64_be_write (doubledata, psf->header + psf->headindex) ;
664 double64_le_write (doubledata, psf->header + psf->headindex) ;
665 psf->headindex += 8 ;
670 /* Write a C string (guaranteed to have a zero terminator). */
671 strptr = va_arg (argptr, char *) ;
672 size = strlen (strptr) + 1 ;
674 if (psf->rwf_endian == SF_ENDIAN_BIG)
675 header_put_be_int (psf, size) ;
677 header_put_le_int (psf, size) ;
678 memcpy (&(psf->header [psf->headindex]), strptr, size) ;
679 psf->headindex += size ;
680 psf->header [psf->headindex - 1] = 0 ;
686 ** Write an AIFF style string (no zero terminator but possibly
687 ** an extra pad byte if the string length is odd).
689 strptr = va_arg (argptr, char *) ;
690 size = strlen (strptr) ;
691 if (psf->rwf_endian == SF_ENDIAN_BIG)
692 header_put_be_int (psf, size) ;
694 header_put_le_int (psf, size) ;
695 memcpy (&(psf->header [psf->headindex]), strptr, size + 1) ;
697 psf->headindex += size ;
698 psf->header [psf->headindex] = 0 ;
703 bindata = va_arg (argptr, void *) ;
704 size = va_arg (argptr, size_t) ;
705 memcpy (&(psf->header [psf->headindex]), bindata, size) ;
706 psf->headindex += size ;
711 size = va_arg (argptr, size_t) ;
714 { psf->header [psf->headindex] = 0 ;
721 bindata = va_arg (argptr, void *) ;
722 memcpy (&(psf->header [psf->headindex]), bindata, 16) ;
723 psf->headindex += 16 ;
728 size = va_arg (argptr, size_t) ;
729 psf->headindex += size ;
734 psf_log_printf (psf, "*** Invalid format specifier `%c'\n", c) ;
735 psf->error = SFE_INTERNAL ;
742 } /* psf_binheader_writef */
744 /*-----------------------------------------------------------------------------------------------
745 ** Binary header reading functions. Returns number of bytes read.
747 ** Format specifiers are the same as for header write function above with the following
750 ** p - jump a given number of position from start of file.
752 ** If format is NULL, psf_binheader_readf returns the current offset.
755 #if (CPU_IS_BIG_ENDIAN == 1)
756 #define GET_MARKER(ptr) ( ((ptr) [0] << 24) | ((ptr) [1] << 16) | \
757 ((ptr) [2] << 8) | ((ptr) [3]) )
759 #elif (CPU_IS_LITTLE_ENDIAN == 1)
760 #define GET_MARKER(ptr) ( ((ptr) [0]) | ((ptr) [1] << 8) | \
761 ((ptr) [2] << 16) | ((ptr) [3] << 24) )
764 # error "Cannot determine endian-ness of processor."
767 #define GET_LE_SHORT(ptr) ( ((ptr) [1] << 8) | ((ptr) [0]) )
768 #define GET_BE_SHORT(ptr) ( ((ptr) [0] << 8) | ((ptr) [1]) )
770 #define GET_LE_3BYTE(ptr) ( ((ptr) [2] << 16) | ((ptr) [1] << 8) | ((ptr) [0]) )
771 #define GET_BE_3BYTE(ptr) ( ((ptr) [0] << 16) | ((ptr) [1] << 8) | ((ptr) [2]) )
773 #define GET_LE_INT(ptr) ( ((ptr) [3] << 24) | ((ptr) [2] << 16) | \
774 ((ptr) [1] << 8) | ((ptr) [0]) )
776 #define GET_BE_INT(ptr) ( ((ptr) [0] << 24) | ((ptr) [1] << 16) | \
777 ((ptr) [2] << 8) | ((ptr) [3]) )
779 #if (SIZEOF_LONG == 4)
780 #define GET_LE_8BYTE(ptr) ( ((ptr) [3] << 24) | ((ptr) [2] << 16) | \
781 ((ptr) [1] << 8) | ((ptr) [0]) )
783 #define GET_BE_8BYTE(ptr) ( ((ptr) [4] << 24) | ((ptr) [5] << 16) | \
784 ((ptr) [6] << 8) | ((ptr) [7]) )
786 #define GET_LE_8BYTE(ptr) ( (((ptr) [7] * 1L) << 56) | (((ptr) [6] * 1L) << 48) | \
787 (((ptr) [5] * 1L) << 40) | (((ptr) [4] * 1L) << 32) | \
788 (((ptr) [3] * 1L) << 24) | (((ptr) [2] * 1L) << 16) | \
789 (((ptr) [1] * 1L) << 8 ) | ((ptr) [0]))
791 #define GET_BE_8BYTE(ptr) ( (((ptr) [0] * 1L) << 56) | (((ptr) [1] * 1L) << 48) | \
792 (((ptr) [2] * 1L) << 40) | (((ptr) [3] * 1L) << 32) | \
793 (((ptr) [4] * 1L) << 24) | (((ptr) [5] * 1L) << 16) | \
794 (((ptr) [6] * 1L) << 8 ) | ((ptr) [7]))
799 header_read (SF_PRIVATE *psf, void *ptr, int bytes)
802 if (psf->headindex >= SIGNED_SIZEOF (psf->header))
803 { memset (ptr, 0, SIGNED_SIZEOF (psf->header) - psf->headindex) ;
805 /* This is the best that we can do. */
806 psf_fseek (psf, bytes, SEEK_CUR) ;
810 if (psf->headindex + bytes > SIGNED_SIZEOF (psf->header))
813 most = SIGNED_SIZEOF (psf->header) - psf->headindex ;
814 psf_fread (psf->header + psf->headend, 1, most, psf) ;
815 memset (ptr + most, 0, bytes - most) ;
817 psf_fseek (psf, bytes - most, SEEK_CUR) ;
821 if (psf->headindex + bytes > psf->headend)
822 { count = psf_fread (psf->header + psf->headend, 1, bytes - (psf->headend - psf->headindex), psf) ;
823 if (count != bytes - (int) (psf->headend - psf->headindex))
824 { psf_log_printf (psf, "Error : psf_fread returned short count.\n") ;
827 psf->headend += count ;
830 memcpy (ptr, psf->header + psf->headindex, bytes) ;
831 psf->headindex += bytes ;
837 header_seek (SF_PRIVATE *psf, sf_count_t position, int whence)
842 if (position > SIGNED_SIZEOF (psf->header))
843 { /* Too much header to cache so just seek instead. */
844 psf_fseek (psf, position, whence) ;
847 if (position > psf->headend)
848 psf->headend += psf_fread (psf->header + psf->headend, 1, position - psf->headend, psf) ;
849 psf->headindex = position ;
853 if (psf->headindex + position < 0)
856 if (psf->headindex >= SIGNED_SIZEOF (psf->header))
857 { psf_fseek (psf, position, whence) ;
861 if (psf->headindex + position <= psf->headend)
862 { psf->headindex += position ;
866 if (psf->headindex + position > SIGNED_SIZEOF (psf->header))
867 { /* Need to jump this without caching it. */
868 psf->headindex = psf->headend ;
869 psf_fseek (psf, position, SEEK_CUR) ;
873 psf->headend += psf_fread (psf->header + psf->headend, 1, position - (psf->headend - psf->headindex), psf) ;
874 psf->headindex = psf->headend ;
879 psf_log_printf (psf, "Bad whence param in header_seek().\n") ;
887 header_gets (SF_PRIVATE *psf, char *ptr, int bufsize)
891 for (k = 0 ; k < bufsize - 1 ; k++)
892 { if (psf->headindex < psf->headend)
893 { ptr [k] = psf->header [psf->headindex] ;
897 { psf->headend += psf_fread (psf->header + psf->headend, 1, 1, psf) ;
898 ptr [k] = psf->header [psf->headindex] ;
899 psf->headindex = psf->headend ;
912 psf_binheader_readf (SF_PRIVATE *psf, char const *format, ...)
914 sf_count_t *countptr, countdata ;
915 unsigned char *ucptr, sixteen_bytes [16] ;
916 unsigned int *intptr, intdata ;
917 unsigned short *shortptr ;
922 int byte_count = 0, count ;
925 return psf_ftell (psf) ;
927 va_start (argptr, format) ;
929 while ((c = *format++))
931 { case 'e' : /* All conversions are now from LE to host. */
932 psf->rwf_endian = SF_ENDIAN_LITTLE ;
935 case 'E' : /* All conversions are now from BE to host. */
936 psf->rwf_endian = SF_ENDIAN_BIG ;
940 intptr = va_arg (argptr, unsigned int*) ;
941 ucptr = (unsigned char*) intptr ;
942 byte_count += header_read (psf, ucptr, sizeof (int)) ;
943 *intptr = GET_MARKER (ucptr) ;
947 intptr = va_arg (argptr, unsigned int*) ;
948 ucptr = (unsigned char*) intptr ;
949 byte_count += header_read (psf, sixteen_bytes, sizeof (sixteen_bytes)) ;
952 for (k = 0 ; k < 16 ; k++)
953 intdata ^= sixteen_bytes [k] << k ;
959 charptr = va_arg (argptr, char*) ;
961 byte_count += header_read (psf, charptr, sizeof (char)) ;
965 shortptr = va_arg (argptr, unsigned short*) ;
967 ucptr = (unsigned char*) shortptr ;
968 byte_count += header_read (psf, ucptr, sizeof (short)) ;
969 if (psf->rwf_endian == SF_ENDIAN_BIG)
970 *shortptr = GET_BE_SHORT (ucptr) ;
972 *shortptr = GET_LE_SHORT (ucptr) ;
976 intptr = va_arg (argptr, unsigned int*) ;
978 byte_count += header_read (psf, sixteen_bytes, 3) ;
979 if (psf->rwf_endian == SF_ENDIAN_BIG)
980 *intptr = GET_BE_3BYTE (sixteen_bytes) ;
982 *intptr = GET_LE_3BYTE (sixteen_bytes) ;
986 intptr = va_arg (argptr, unsigned int*) ;
988 ucptr = (unsigned char*) intptr ;
989 byte_count += header_read (psf, ucptr, sizeof (int)) ;
990 if (psf->rwf_endian == SF_ENDIAN_BIG)
991 *intptr = GET_BE_INT (ucptr) ;
993 *intptr = GET_LE_INT (ucptr) ;
997 countptr = va_arg (argptr, sf_count_t *) ;
999 byte_count += header_read (psf, sixteen_bytes, 8) ;
1000 if (psf->rwf_endian == SF_ENDIAN_BIG)
1001 countdata = GET_BE_8BYTE (sixteen_bytes) ;
1003 countdata = GET_LE_8BYTE (sixteen_bytes) ;
1004 *countptr = countdata ;
1007 case 'f' : /* Float conversion */
1008 floatptr = va_arg (argptr, float *) ;
1010 byte_count += header_read (psf, floatptr, sizeof (float)) ;
1011 if (psf->rwf_endian == SF_ENDIAN_BIG)
1012 *floatptr = float32_be_read ((unsigned char*) floatptr) ;
1014 *floatptr = float32_le_read ((unsigned char*) floatptr) ;
1017 case 'd' : /* double conversion */
1018 doubleptr = va_arg (argptr, double *) ;
1020 byte_count += header_read (psf, doubleptr, sizeof (double)) ;
1021 if (psf->rwf_endian == SF_ENDIAN_BIG)
1022 *doubleptr = double64_be_read ((unsigned char*) doubleptr) ;
1024 *doubleptr = double64_le_read ((unsigned char*) doubleptr) ;
1028 psf_log_printf (psf, "Format conversion 's' not implemented yet.\n") ;
1030 strptr = va_arg (argptr, char *) ;
1031 size = strlen (strptr) + 1 ;
1032 size += (size & 1) ;
1033 longdata = H2LE_INT (size) ;
1034 get_int (psf, longdata) ;
1035 memcpy (&(psf->header [psf->headindex]), strptr, size) ;
1036 psf->headindex += size ;
1041 charptr = va_arg (argptr, char*) ;
1042 count = va_arg (argptr, int) ;
1044 byte_count += header_read (psf, charptr, count) ;
1048 charptr = va_arg (argptr, char*) ;
1049 count = va_arg (argptr, int) ;
1051 byte_count += header_gets (psf, charptr, count) ;
1055 psf_log_printf (psf, "Format conversion 'z' not implemented yet.\n") ;
1057 size = va_arg (argptr, size_t) ;
1059 { psf->header [psf->headindex] = 0 ;
1067 /* Get the seek position first. */
1068 count = va_arg (argptr, int) ;
1069 header_seek (psf, count, SEEK_SET) ;
1070 byte_count = count ;
1074 /* Get the seek position first. */
1075 count = va_arg (argptr, int) ;
1076 header_seek (psf, count, SEEK_CUR) ;
1077 byte_count += count ;
1081 psf_log_printf (psf, "*** Invalid format specifier `%c'\n", c) ;
1082 psf->error = SFE_INTERNAL ;
1090 } /* psf_binheader_readf */
1092 /*-----------------------------------------------------------------------------------------------
1096 psf_default_seek (SF_PRIVATE *psf, int mode, sf_count_t samples_from_start)
1097 { sf_count_t position, retval ;
1099 if (! (psf->blockwidth && psf->dataoffset >= 0))
1100 { psf->error = SFE_BAD_SEEK ;
1101 return PSF_SEEK_ERROR ;
1104 if (! psf->sf.seekable)
1105 { psf->error = SFE_NOT_SEEKABLE ;
1106 return PSF_SEEK_ERROR ;
1109 position = psf->dataoffset + psf->blockwidth * samples_from_start ;
1111 if ((retval = psf_fseek (psf, position, SEEK_SET)) != position)
1112 { psf->error = SFE_SEEK_FAILED ;
1113 return PSF_SEEK_ERROR ;
1118 return samples_from_start ;
1119 } /* psf_default_seek */
1121 /*-----------------------------------------------------------------------------------------------
1125 psf_hexdump (void *ptr, int len)
1126 { char ascii [17], *data ;
1129 if ((data = ptr) == NULL)
1135 for (k = 0 ; k < len ; k += 16)
1136 { memset (ascii, ' ', sizeof (ascii)) ;
1138 printf ("%08X: ", k) ;
1139 for (m = 0 ; m < 16 && k + m < len ; m++)
1140 { printf (m == 8 ? " %02X " : "%02X ", data [k + m] & 0xFF) ;
1141 ascii [m] = isprint (data [k + m]) ? data [k + m] : '.' ;
1144 if (m <= 8) printf (" ") ;
1145 for ( ; m < 16 ; m++) printf (" ") ;
1148 printf (" %s\n", ascii) ;
1155 psf_log_SF_INFO (SF_PRIVATE *psf)
1156 { psf_log_printf (psf, "---------------------------------\n") ;
1158 psf_log_printf (psf, " Sample rate : %d\n", psf->sf.samplerate) ;
1159 psf_log_printf (psf, " Frames : %D\n", psf->sf.frames) ;
1160 psf_log_printf (psf, " Channels : %d\n", psf->sf.channels) ;
1162 psf_log_printf (psf, " Format : 0x%X\n", psf->sf.format) ;
1163 psf_log_printf (psf, " Sections : %d\n", psf->sf.sections) ;
1164 psf_log_printf (psf, " Seekable : %s\n", psf->sf.seekable ? "TRUE" : "FALSE") ;
1166 psf_log_printf (psf, "---------------------------------\n") ;
1167 } /* psf_dump_SFINFO */
1169 /*========================================================================================
1173 psf_instrument_alloc (void)
1174 { SF_INSTRUMENT *instr ;
1176 instr = calloc (1, sizeof (SF_INSTRUMENT)) ;
1181 /* Set non-zero default values. */
1182 instr->basenote = -1 ;
1183 instr->velocity_lo = -1 ;
1184 instr->velocity_hi = -1 ;
1185 instr->key_lo = -1 ;
1186 instr->key_hi = -1 ;
1189 } /* psf_instrument_alloc */
1192 psf_memset (void *s, int c, sf_count_t len)
1199 { setcount = (len > 0x10000000) ? 0x10000000 : (int) len ;
1201 memset (ptr, c, setcount) ;
1210 void psf_get_date_str (char *str, int maxlen)
1212 struct tm timedata, *tmptr ;
1216 #if defined (HAVE_GMTIME_R)
1217 /* If the re-entrant version is available, use it. */
1218 tmptr = gmtime_r (¤t, &timedata) ;
1219 #elif defined (HAVE_GMTIME)
1220 /* Otherwise use the standard one and copy the data to local storage. */
1221 tmptr = gmtime (¤t) ;
1222 memcpy (&timedata, tmptr, sizeof (timedata)) ;
1228 LSF_SNPRINTF (str, maxlen, "%4d-%02d-%02d %02d:%02d:%02d UTC",
1229 1900 + timedata.tm_year, timedata.tm_mon, timedata.tm_mday,
1230 timedata.tm_hour, timedata.tm_min, timedata.tm_sec) ;
1232 LSF_SNPRINTF (str, maxlen, "Unknown date") ;
1235 } /* psf_get_date_str */
1238 subformat_to_bytewidth (int format)
1241 { case SF_FORMAT_PCM_U8 :
1242 case SF_FORMAT_PCM_S8 :
1244 case SF_FORMAT_PCM_16 :
1246 case SF_FORMAT_PCM_24 :
1248 case SF_FORMAT_PCM_32 :
1249 case SF_FORMAT_FLOAT :
1251 case SF_FORMAT_DOUBLE :
1256 } /* subformat_to_bytewidth */
1259 s_bitwidth_to_subformat (int bits)
1260 { static int array [] =
1261 { SF_FORMAT_PCM_S8, SF_FORMAT_PCM_16, SF_FORMAT_PCM_24, SF_FORMAT_PCM_32
1264 if (bits < 8 || bits > 32)
1267 return array [((bits + 7) / 8) - 1] ;
1268 } /* bitwidth_to_subformat */
1271 u_bitwidth_to_subformat (int bits)
1272 { static int array [] =
1273 { SF_FORMAT_PCM_U8, SF_FORMAT_PCM_16, SF_FORMAT_PCM_24, SF_FORMAT_PCM_32
1276 if (bits < 8 || bits > 32)
1279 return array [((bits + 7) / 8) - 1] ;
1280 } /* bitwidth_to_subformat */
1282 #endif /* PSF_LOG_PRINTF_ONLY */
1285 ** Do not edit or modify anything in this comment block.
1286 ** The arch-tag line is a file identity tag for the GNU Arch
1287 ** revision control system.
1289 ** arch-tag: 33e9795e-f717-461a-9feb-65d083a56395