1/* 2** Copyright (C) 1999-2019 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#if HAVE_UNISTD_H 24#include <unistd.h> 25#else 26#include "sf_unistd.h" 27#endif 28#include <ctype.h> 29#include <math.h> 30#include <time.h> 31#if HAVE_SYS_TIME_H 32#include <sys/time.h> 33#endif 34#include "sndfile.h" 35#include "sfendian.h" 36#include "common.h" 37 38#define INITIAL_HEADER_SIZE 256 39 40/* Allocate and initialize the SF_PRIVATE struct. */ 41SF_PRIVATE * 42psf_allocate (void) 43{ SF_PRIVATE * psf ; 44 45 if ((psf = calloc (1, sizeof (SF_PRIVATE))) == NULL) 46 return NULL ; 47 48 if ((psf->header.ptr = calloc (1, INITIAL_HEADER_SIZE)) == NULL) 49 { free (psf) ; 50 return NULL ; 51 } ; 52 psf->header.len = INITIAL_HEADER_SIZE ; 53 54 return psf ; 55} /* psf_allocate */ 56 57static int 58psf_bump_header_allocation (SF_PRIVATE * psf, sf_count_t needed) 59{ 60 sf_count_t newlen, smallest = INITIAL_HEADER_SIZE ; 61 void * ptr ; 62 63 newlen = (needed > psf->header.len) ? 2 * SF_MAX (needed, smallest) : 2 * psf->header.len ; 64 65 if (newlen > 100 * 1024) 66 { psf_log_printf (psf, "Request for header allocation of %D denied.\n", newlen) ; 67 return 1 ; 68 } 69 70 if ((ptr = realloc (psf->header.ptr, newlen)) == NULL) 71 { psf_log_printf (psf, "realloc (%p, %D) failed\n", psf->header.ptr, newlen) ; 72 psf->error = SFE_MALLOC_FAILED ; 73 return 1 ; 74 } ; 75 76 /* Always zero-out new header memory to avoid un-initializer memory accesses. */ 77 if (newlen > psf->header.len) 78 memset ((char *) ptr + psf->header.len, 0, newlen - psf->header.len) ; 79 80 psf->header.ptr = ptr ; 81 psf->header.len = newlen ; 82 return 0 ; 83} /* psf_bump_header_allocation */ 84 85/*----------------------------------------------------------------------------------------------- 86** psf_log_printf allows libsndfile internal functions to print to an internal parselog which 87** can later be displayed. 88** The format specifiers are as for printf but without the field width and other modifiers. 89** Printing is performed to the parselog char array of the SF_PRIVATE struct. 90** Printing is done in such a way as to guarantee that the log never overflows the end of the 91** parselog array. 92*/ 93 94static inline void 95log_putchar (SF_PRIVATE *psf, char ch) 96{ if (psf->parselog.indx < SIGNED_SIZEOF (psf->parselog.buf) - 1) 97 { psf->parselog.buf [psf->parselog.indx++] = ch ; 98 psf->parselog.buf [psf->parselog.indx] = 0 ; 99 } ; 100 return ; 101} /* log_putchar */ 102 103void 104psf_log_printf (SF_PRIVATE *psf, const char *format, ...) 105{ va_list ap ; 106 uint32_t u, tens ; 107 int d, shift, width, width_specifier, left_align, slen, precision ; 108 char c, *strptr, istr [5], lead_char, sign_char ; 109 110 va_start (ap, format) ; 111 112 while ((c = *format++)) 113 { if (c != '%') 114 { log_putchar (psf, c) ; 115 continue ; 116 } ; 117 118 if (format [0] == '%') /* Handle %% */ 119 { log_putchar (psf, '%') ; 120 format ++ ; 121 continue ; 122 } ; 123 124 sign_char = 0 ; 125 left_align = SF_FALSE ; 126 while (1) 127 { switch (format [0]) 128 { case ' ' : 129 case '+' : 130 sign_char = format [0] ; 131 format ++ ; 132 continue ; 133 134 case '-' : 135 left_align = SF_TRUE ; 136 format ++ ; 137 continue ; 138 139 default : break ; 140 } ; 141 142 break ; 143 } ; 144 145 if (format [0] == 0) 146 break ; 147 148 lead_char = ' ' ; 149 if (format [0] == '0') 150 lead_char = '0' ; 151 152 width_specifier = 0 ; 153 while ((c = *format++) && isdigit (c)) 154 width_specifier = width_specifier * 10 + (c - '0') ; 155 156 precision = 0 ; 157 if (c == '.') 158 { while ((c = *format++) && isdigit (c)) 159 precision = precision * 10 + (c - '0') ; 160 } ; 161 162 switch (c) 163 { case 0 : /* NULL character. */ 164 va_end (ap) ; 165 return ; 166 167 case 's': /* string */ 168 strptr = va_arg (ap, char *) ; 169 if (strptr == NULL) 170 break ; 171 if (precision > 0) 172 slen = strnlen (strptr, precision) ; 173 else 174 slen = strlen (strptr) ; 175 width_specifier = width_specifier >= slen ? width_specifier - slen : 0 ; 176 if (left_align == SF_FALSE) 177 while (width_specifier -- > 0) 178 log_putchar (psf, ' ') ; 179 while (slen--) 180 log_putchar (psf, *strptr++) ; 181 while (width_specifier -- > 0) 182 log_putchar (psf, ' ') ; 183 break ; 184 185 case 'd': /* int */ 186 d = va_arg (ap, int) ; 187 188 if (d < 0) 189 { sign_char = '-' ; 190 if (lead_char != '0' && left_align == SF_FALSE) 191 width_specifier -- ; 192 193 u = - ((unsigned) d) ; 194 } 195 else 196 { u = (unsigned) d ; 197 } 198 199 tens = 1 ; 200 width = 1 ; 201 while (u / tens >= 10) 202 { tens *= 10 ; 203 width ++ ; 204 } ; 205 206 width_specifier -= width ; 207 208 if (sign_char == ' ') 209 { log_putchar (psf, ' ') ; 210 width_specifier -- ; 211 } ; 212 213 if (left_align == SF_FALSE && lead_char != '0') 214 { if (sign_char == '+') 215 width_specifier -- ; 216 217 while (width_specifier -- > 0) 218 log_putchar (psf, lead_char) ; 219 } ; 220 221 if (sign_char == '+' || sign_char == '-') 222 { log_putchar (psf, sign_char) ; 223 width_specifier -- ; 224 } ; 225 226 if (left_align == SF_FALSE) 227 while (width_specifier -- > 0) 228 log_putchar (psf, lead_char) ; 229 230 while (tens > 0) 231 { log_putchar (psf, '0' + u / tens) ; 232 u %= tens ; 233 tens /= 10 ; 234 } ; 235 236 while (width_specifier -- > 0) 237 log_putchar (psf, lead_char) ; 238 break ; 239 240 case 'D': /* sf_count_t */ 241 { sf_count_t D ; 242 uint64_t U, Tens ; 243 244 D = va_arg (ap, sf_count_t) ; 245 246 if (D == 0) 247 { while (-- width_specifier > 0) 248 log_putchar (psf, lead_char) ; 249 log_putchar (psf, '0') ; 250 break ; 251 } 252 else 253 { if (D < 0) 254 { log_putchar (psf, '-') ; 255 U = -((uint64_t) D) ; 256 } 257 else 258 { U = (uint64_t) D; 259 } 260 } 261 262 Tens = 1 ; 263 width = 1 ; 264 while (U / Tens >= 10) 265 { Tens *= 10 ; 266 width ++ ; 267 } ; 268 269 while (width_specifier > width) 270 { log_putchar (psf, lead_char) ; 271 width_specifier-- ; 272 } ; 273 274 while (Tens > 0) 275 { log_putchar (psf, '0' + U / Tens) ; 276 U %= Tens ; 277 Tens /= 10 ; 278 } ; 279 } ; 280 break ; 281 282 case 'u': /* unsigned int */ 283 u = va_arg (ap, unsigned int) ; 284 285 tens = 1 ; 286 width = 1 ; 287 while (u / tens >= 10) 288 { tens *= 10 ; 289 width ++ ; 290 } ; 291 292 width_specifier -= width ; 293 294 if (sign_char == ' ') 295 { log_putchar (psf, ' ') ; 296 width_specifier -- ; 297 } ; 298 299 if (left_align == SF_FALSE && lead_char != '0') 300 { if (sign_char == '+') 301 width_specifier -- ; 302 303 while (width_specifier -- > 0) 304 log_putchar (psf, lead_char) ; 305 } ; 306 307 if (sign_char == '+' || sign_char == '-') 308 { log_putchar (psf, sign_char) ; 309 width_specifier -- ; 310 } ; 311 312 if (left_align == SF_FALSE) 313 while (width_specifier -- > 0) 314 log_putchar (psf, lead_char) ; 315 316 while (tens > 0) 317 { log_putchar (psf, '0' + u / tens) ; 318 u %= tens ; 319 tens /= 10 ; 320 } ; 321 322 while (width_specifier -- > 0) 323 log_putchar (psf, lead_char) ; 324 break ; 325 326 case 'c': /* char */ 327 c = va_arg (ap, int) & 0xFF ; 328 log_putchar (psf, c) ; 329 break ; 330 331 case 'x': /* hex */ 332 case 'X': /* hex */ 333 d = va_arg (ap, int) ; 334 335 if (d == 0) 336 { while (--width_specifier > 0) 337 log_putchar (psf, lead_char) ; 338 log_putchar (psf, '0') ; 339 break ; 340 } ; 341 shift = 28 ; 342 width = (width_specifier < 8) ? 8 : width_specifier ; 343 while (! ((((uint32_t) 0xF) << shift) & d)) 344 { shift -= 4 ; 345 width -- ; 346 } ; 347 348 while (width > 0 && width_specifier > width) 349 { log_putchar (psf, lead_char) ; 350 width_specifier-- ; 351 } ; 352 353 while (shift >= 0) 354 { c = (d >> shift) & 0xF ; 355 log_putchar (psf, (c > 9) ? c + 'A' - 10 : c + '0') ; 356 shift -= 4 ; 357 } ; 358 break ; 359 360 case 'M': /* int2str */ 361 d = va_arg (ap, int) ; 362 if (CPU_IS_LITTLE_ENDIAN) 363 { istr [0] = d & 0xFF ; 364 istr [1] = (d >> 8) & 0xFF ; 365 istr [2] = (d >> 16) & 0xFF ; 366 istr [3] = (d >> 24) & 0xFF ; 367 } 368 else 369 { istr [3] = d & 0xFF ; 370 istr [2] = (d >> 8) & 0xFF ; 371 istr [1] = (d >> 16) & 0xFF ; 372 istr [0] = (d >> 24) & 0xFF ; 373 } ; 374 istr [4] = 0 ; 375 strptr = istr ; 376 while (*strptr) 377 { c = *strptr++ ; 378 log_putchar (psf, psf_isprint (c) ? c : '.') ; 379 } ; 380 break ; 381 382 default : 383 log_putchar (psf, '*') ; 384 log_putchar (psf, c) ; 385 log_putchar (psf, '*') ; 386 break ; 387 } /* switch */ 388 } /* while */ 389 390 va_end (ap) ; 391 return ; 392} /* psf_log_printf */ 393 394/*----------------------------------------------------------------------------------------------- 395** ASCII header printf functions. 396** Some formats (ie NIST) use ascii text in their headers. 397** Format specifiers are the same as the standard printf specifiers (uses vsnprintf). 398** If this generates a compile error on any system, the author should be notified 399** so an alternative vsnprintf can be provided. 400*/ 401 402void 403psf_asciiheader_printf (SF_PRIVATE *psf, const char *format, ...) 404{ va_list argptr ; 405 int maxlen ; 406 char *start ; 407 408 if (! format) 409 return ; 410 411 maxlen = strlen ((char*) psf->header.ptr) ; 412 start = ((char*) psf->header.ptr) + maxlen ; 413 maxlen = psf->header.len - maxlen ; 414 415 va_start (argptr, format) ; 416 vsnprintf (start, maxlen, format, argptr) ; 417 va_end (argptr) ; 418 419 /* Make sure the string is properly terminated. */ 420 start [maxlen - 1] = 0 ; 421 422 psf->header.indx = strlen ((char*) psf->header.ptr) ; 423 424 return ; 425} /* psf_asciiheader_printf */ 426 427/*----------------------------------------------------------------------------------------------- 428** Binary header writing functions. Returns number of bytes written. 429** 430** Format specifiers for psf_binheader_writef are as follows 431** m - marker - four bytes - no endian manipulation 432** 433** e - all following numerical values will be little endian 434** E - all following numerical values will be big endian 435** 436** t - all following O types will be truncated to 4 bytes 437** T - switch off truncation of all following O types 438** 439** 1 - single byte value 440** 2 - two byte value 441** 3 - three byte value 442** 4 - four byte value 443** 8 - eight byte value (sometimes written as 4 bytes) 444** 445** s - string preceded by a four byte length 446** S - string including null terminator 447** p - a Pascal string 448** 449** f - floating point data 450** d - double precision floating point data 451** h - 16 binary bytes value 452** 453** b - binary data (see below) 454** z - zero bytes (ses below) 455** j - jump forwards or backwards 456** 457** To write a word followed by an int (both little endian) use: 458** psf_binheader_writef ("e24", wordval, longval) ; 459** 460** To write binary data use: 461** psf_binheader_writef ("b", &bindata, sizeof (bindata)) ; 462** 463** To write N zero bytes use: 464** NOTE: due to platform issues (ie x86-64) you should cast the 465** argument to size_t or ensure the variable type is size_t. 466** psf_binheader_writef ("z", N) ; 467*/ 468 469/* These macros may seem a bit messy but do prevent problems with processors which 470** seg. fault when asked to write an int or short to a non-int/short aligned address. 471*/ 472 473static inline void 474header_put_byte (SF_PRIVATE *psf, char x) 475{ psf->header.ptr [psf->header.indx++] = x ; 476} /* header_put_byte */ 477 478#if (CPU_IS_BIG_ENDIAN == 1) 479static inline void 480header_put_marker (SF_PRIVATE *psf, int x) 481{ psf->header.ptr [psf->header.indx++] = (x >> 24) ; 482 psf->header.ptr [psf->header.indx++] = (x >> 16) ; 483 psf->header.ptr [psf->header.indx++] = (x >> 8) ; 484 psf->header.ptr [psf->header.indx++] = x ; 485} /* header_put_marker */ 486 487#elif (CPU_IS_LITTLE_ENDIAN == 1) 488static inline void 489header_put_marker (SF_PRIVATE *psf, int x) 490{ psf->header.ptr [psf->header.indx++] = x ; 491 psf->header.ptr [psf->header.indx++] = (x >> 8) ; 492 psf->header.ptr [psf->header.indx++] = (x >> 16) ; 493 psf->header.ptr [psf->header.indx++] = (x >> 24) ; 494} /* header_put_marker */ 495 496#else 497# error "Cannot determine endian-ness of processor." 498#endif 499 500 501static inline void 502header_put_be_short (SF_PRIVATE *psf, int x) 503{ psf->header.ptr [psf->header.indx++] = (x >> 8) ; 504 psf->header.ptr [psf->header.indx++] = x ; 505} /* header_put_be_short */ 506 507static inline void 508header_put_le_short (SF_PRIVATE *psf, int x) 509{ psf->header.ptr [psf->header.indx++] = x ; 510 psf->header.ptr [psf->header.indx++] = (x >> 8) ; 511} /* header_put_le_short */ 512 513static inline void 514header_put_be_3byte (SF_PRIVATE *psf, int x) 515{ psf->header.ptr [psf->header.indx++] = (x >> 16) ; 516 psf->header.ptr [psf->header.indx++] = (x >> 8) ; 517 psf->header.ptr [psf->header.indx++] = x ; 518} /* header_put_be_3byte */ 519 520static inline void 521header_put_le_3byte (SF_PRIVATE *psf, int x) 522{ psf->header.ptr [psf->header.indx++] = x ; 523 psf->header.ptr [psf->header.indx++] = (x >> 8) ; 524 psf->header.ptr [psf->header.indx++] = (x >> 16) ; 525} /* header_put_le_3byte */ 526 527static inline void 528header_put_be_int (SF_PRIVATE *psf, int x) 529{ psf->header.ptr [psf->header.indx++] = (x >> 24) ; 530 psf->header.ptr [psf->header.indx++] = (x >> 16) ; 531 psf->header.ptr [psf->header.indx++] = (x >> 8) ; 532 psf->header.ptr [psf->header.indx++] = x ; 533} /* header_put_be_int */ 534 535static inline void 536header_put_le_int (SF_PRIVATE *psf, int x) 537{ psf->header.ptr [psf->header.indx++] = x ; 538 psf->header.ptr [psf->header.indx++] = (x >> 8) ; 539 psf->header.ptr [psf->header.indx++] = (x >> 16) ; 540 psf->header.ptr [psf->header.indx++] = (x >> 24) ; 541} /* header_put_le_int */ 542 543static inline void 544header_put_be_8byte (SF_PRIVATE *psf, sf_count_t x) 545{ psf->header.ptr [psf->header.indx++] = (x >> 56) ; 546 psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 48) ; 547 psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 40) ; 548 psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 32) ; 549 psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 24) ; 550 psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 16) ; 551 psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 8) ; 552 psf->header.ptr [psf->header.indx++] = (unsigned char) x ; 553} /* header_put_be_8byte */ 554 555static inline void 556header_put_le_8byte (SF_PRIVATE *psf, sf_count_t x) 557{ psf->header.ptr [psf->header.indx++] = (unsigned char) x ; 558 psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 8) ; 559 psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 16) ; 560 psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 24) ; 561 psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 32) ; 562 psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 40) ; 563 psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 48) ; 564 psf->header.ptr [psf->header.indx++] = (x >> 56) ; 565} /* header_put_le_8byte */ 566 567int 568psf_binheader_writef (SF_PRIVATE *psf, const char *format, ...) 569{ va_list argptr ; 570 sf_count_t countdata ; 571 unsigned long longdata ; 572 unsigned int data ; 573 float floatdata ; 574 double doubledata ; 575 void *bindata ; 576 size_t size ; 577 char c, *strptr ; 578 int count = 0, trunc_8to4 = SF_FALSE ; 579 580 if (! format) 581 return psf_ftell (psf) ; 582 583 va_start (argptr, format) ; 584 585 while ((c = *format++)) 586 { 587 if (psf->header.indx + 16 >= psf->header.len && psf_bump_header_allocation (psf, 16)) 588 break ; 589 590 switch (c) 591 { case ' ' : /* Do nothing. Just used to space out format string. */ 592 break ; 593 594 case 'e' : /* All conversions are now from LE to host. */ 595 psf->rwf_endian = SF_ENDIAN_LITTLE ; 596 break ; 597 598 case 'E' : /* All conversions are now from BE to host. */ 599 psf->rwf_endian = SF_ENDIAN_BIG ; 600 break ; 601 602 case 't' : /* All 8 byte values now get written as 4 bytes. */ 603 trunc_8to4 = SF_TRUE ; 604 break ; 605 606 case 'T' : /* All 8 byte values now get written as 8 bytes. */ 607 trunc_8to4 = SF_FALSE ; 608 break ; 609 610 case 'm' : 611 data = va_arg (argptr, unsigned int) ; 612 header_put_marker (psf, data) ; 613 count += 4 ; 614 break ; 615 616 case '1' : 617 data = va_arg (argptr, unsigned int) ; 618 header_put_byte (psf, data) ; 619 count += 1 ; 620 break ; 621 622 case '2' : 623 data = va_arg (argptr, unsigned int) ; 624 if (psf->rwf_endian == SF_ENDIAN_BIG) 625 { header_put_be_short (psf, data) ; 626 } 627 else 628 { header_put_le_short (psf, data) ; 629 } ; 630 count += 2 ; 631 break ; 632 633 case '3' : /* tribyte */ 634 data = va_arg (argptr, unsigned int) ; 635 if (psf->rwf_endian == SF_ENDIAN_BIG) 636 { header_put_be_3byte (psf, data) ; 637 } 638 else 639 { header_put_le_3byte (psf, data) ; 640 } ; 641 count += 3 ; 642 break ; 643 644 case '4' : 645 data = va_arg (argptr, unsigned int) ; 646 if (psf->rwf_endian == SF_ENDIAN_BIG) 647 { header_put_be_int (psf, data) ; 648 } 649 else 650 { header_put_le_int (psf, data) ; 651 } ; 652 count += 4 ; 653 break ; 654 655 case '8' : 656 countdata = va_arg (argptr, sf_count_t) ; 657 if (psf->rwf_endian == SF_ENDIAN_BIG && trunc_8to4 == SF_FALSE) 658 { header_put_be_8byte (psf, countdata) ; 659 count += 8 ; 660 } 661 else if (psf->rwf_endian == SF_ENDIAN_LITTLE && trunc_8to4 == SF_FALSE) 662 { header_put_le_8byte (psf, countdata) ; 663 count += 8 ; 664 } 665 else if (psf->rwf_endian == SF_ENDIAN_BIG && trunc_8to4 == SF_TRUE) 666 { longdata = countdata & 0xFFFFFFFF ; 667 header_put_be_int (psf, longdata) ; 668 count += 4 ; 669 } 670 else if (psf->rwf_endian == SF_ENDIAN_LITTLE && trunc_8to4 == SF_TRUE) 671 { longdata = countdata & 0xFFFFFFFF ; 672 header_put_le_int (psf, longdata) ; 673 count += 4 ; 674 } 675 break ; 676 677 case 'f' : 678 /* Floats are passed as doubles. Is this always true? */ 679 floatdata = (float) va_arg (argptr, double) ; 680 if (psf->rwf_endian == SF_ENDIAN_BIG) 681 float32_be_write (floatdata, psf->header.ptr + psf->header.indx) ; 682 else 683 float32_le_write (floatdata, psf->header.ptr + psf->header.indx) ; 684 psf->header.indx += 4 ; 685 count += 4 ; 686 break ; 687 688 case 'd' : 689 doubledata = va_arg (argptr, double) ; 690 if (psf->rwf_endian == SF_ENDIAN_BIG) 691 double64_be_write (doubledata, psf->header.ptr + psf->header.indx) ; 692 else 693 double64_le_write (doubledata, psf->header.ptr + psf->header.indx) ; 694 psf->header.indx += 8 ; 695 count += 8 ; 696 break ; 697 698 case 's' : 699 /* Write a C string (guaranteed to have a zero terminator). */ 700 strptr = va_arg (argptr, char *) ; 701 size = strlen (strptr) + 1 ; 702 703 if (psf->header.indx + 4 + (sf_count_t) size + (sf_count_t) (size & 1) > psf->header.len && psf_bump_header_allocation (psf, 4 + size + (size & 1))) 704 break ; 705 706 if (psf->rwf_endian == SF_ENDIAN_BIG) 707 header_put_be_int (psf, size + (size & 1)) ; 708 else 709 header_put_le_int (psf, size + (size & 1)) ; 710 memcpy (&(psf->header.ptr [psf->header.indx]), strptr, size) ; 711 size += (size & 1) ; 712 psf->header.indx += size ; 713 psf->header.ptr [psf->header.indx - 1] = 0 ; 714 count += 4 + size ; 715 break ; 716 717 case 'S' : 718 /* 719 ** Write an AIFF style string (no zero terminator but possibly 720 ** an extra pad byte if the string length is odd). 721 */ 722 strptr = va_arg (argptr, char *) ; 723 size = strlen (strptr) ; 724 if (psf->header.indx + 4 + (sf_count_t) size + (sf_count_t) (size & 1) > psf->header.len && psf_bump_header_allocation (psf, 4 + size + (size & 1))) 725 break ; 726 if (psf->rwf_endian == SF_ENDIAN_BIG) 727 header_put_be_int (psf, size) ; 728 else 729 header_put_le_int (psf, size) ; 730 memcpy (&(psf->header.ptr [psf->header.indx]), strptr, size + (size & 1)) ; 731 size += (size & 1) ; 732 psf->header.indx += size ; 733 count += 4 + size ; 734 break ; 735 736 case 'p' : 737 /* Write a PASCAL string (as used by AIFF files). 738 */ 739 strptr = va_arg (argptr, char *) ; 740 size = strlen (strptr) ; 741 size = (size & 1) ? size : size + 1 ; 742 size = (size > 254) ? 254 : size ; 743 744 if (psf->header.indx + 1 + (sf_count_t) size > psf->header.len && psf_bump_header_allocation (psf, 1 + size)) 745 break ; 746 747 header_put_byte (psf, size) ; 748 memcpy (&(psf->header.ptr [psf->header.indx]), strptr, size) ; 749 psf->header.indx += size ; 750 count += 1 + size ; 751 break ; 752 753 case 'b' : 754 bindata = va_arg (argptr, void *) ; 755 size = va_arg (argptr, size_t) ; 756 757 if (psf->header.indx + (sf_count_t) size > psf->header.len && psf_bump_header_allocation (psf, size)) 758 break ; 759 760 memcpy (&(psf->header.ptr [psf->header.indx]), bindata, size) ; 761 psf->header.indx += size ; 762 count += size ; 763 break ; 764 765 case 'z' : 766 size = va_arg (argptr, size_t) ; 767 768 if (psf->header.indx + (sf_count_t) size > psf->header.len && psf_bump_header_allocation (psf, size)) 769 break ; 770 771 count += size ; 772 while (size) 773 { psf->header.ptr [psf->header.indx] = 0 ; 774 psf->header.indx ++ ; 775 size -- ; 776 } ; 777 break ; 778 779 case 'h' : 780 bindata = va_arg (argptr, void *) ; 781 memcpy (&(psf->header.ptr [psf->header.indx]), bindata, 16) ; 782 psf->header.indx += 16 ; 783 count += 16 ; 784 break ; 785 786 case 'j' : /* Jump forwards/backwards by specified amount. */ 787 size = va_arg (argptr, size_t) ; 788 789 if (psf->header.indx + (sf_count_t) size > psf->header.len && psf_bump_header_allocation (psf, size)) 790 break ; 791 792 psf->header.indx += size ; 793 count += size ; 794 break ; 795 796 case 'o' : /* Jump to specified offset. */ 797 size = va_arg (argptr, size_t) ; 798 799 if ((sf_count_t) size >= psf->header.len && psf_bump_header_allocation (psf, size)) 800 break ; 801 802 psf->header.indx = size ; 803 break ; 804 805 default : 806 psf_log_printf (psf, "*** Invalid format specifier `%c'\n", c) ; 807 psf->error = SFE_INTERNAL ; 808 break ; 809 } ; 810 } ; 811 812 va_end (argptr) ; 813 return count ; 814} /* psf_binheader_writef */ 815 816/*----------------------------------------------------------------------------------------------- 817** Binary header reading functions. Returns number of bytes read. 818** 819** Format specifiers are the same as for header write function above with the following 820** additions: 821** 822** p - jump a given number of position from start of file. 823** 824** If format is NULL, psf_binheader_readf returns the current offset. 825*/ 826 827#if (CPU_IS_BIG_ENDIAN == 1) 828#define GET_MARKER(ptr) ( (((uint32_t) (ptr) [0]) << 24) | ((ptr) [1] << 16) | \ 829 ((ptr) [2] << 8) | ((ptr) [3])) 830 831#elif (CPU_IS_LITTLE_ENDIAN == 1) 832#define GET_MARKER(ptr) ( ((ptr) [0]) | ((ptr) [1] << 8) | \ 833 ((ptr) [2] << 16) | (((uint32_t) (ptr) [3]) << 24)) 834 835#else 836# error "Cannot determine endian-ness of processor." 837#endif 838 839#define GET_LE_SHORT(ptr) (((ptr) [1] << 8) | ((ptr) [0])) 840#define GET_BE_SHORT(ptr) (((ptr) [0] << 8) | ((ptr) [1])) 841 842#define GET_LE_3BYTE(ptr) ( ((ptr) [2] << 16) | ((ptr) [1] << 8) | ((ptr) [0])) 843#define GET_BE_3BYTE(ptr) ( ((ptr) [0] << 16) | ((ptr) [1] << 8) | ((ptr) [2])) 844 845#define GET_LE_INT(ptr) ( ((ptr) [3] << 24) | ((ptr) [2] << 16) | \ 846 ((ptr) [1] << 8) | ((ptr) [0])) 847 848#define GET_BE_INT(ptr) ( ((ptr) [0] << 24) | ((ptr) [1] << 16) | \ 849 ((ptr) [2] << 8) | ((ptr) [3])) 850 851#define GET_LE_8BYTE(ptr) ( (((sf_count_t) (ptr) [7]) << 56) | (((sf_count_t) (ptr) [6]) << 48) | \ 852 (((sf_count_t) (ptr) [5]) << 40) | (((sf_count_t) (ptr) [4]) << 32) | \ 853 (((sf_count_t) (ptr) [3]) << 24) | (((sf_count_t) (ptr) [2]) << 16) | \ 854 (((sf_count_t) (ptr) [1]) << 8) | ((ptr) [0])) 855 856#define GET_BE_8BYTE(ptr) ( (((sf_count_t) (ptr) [0]) << 56) | (((sf_count_t) (ptr) [1]) << 48) | \ 857 (((sf_count_t) (ptr) [2]) << 40) | (((sf_count_t) (ptr) [3]) << 32) | \ 858 (((sf_count_t) (ptr) [4]) << 24) | (((sf_count_t) (ptr) [5]) << 16) | \ 859 (((sf_count_t) (ptr) [6]) << 8) | ((ptr) [7])) 860 861 862 863static int 864header_read (SF_PRIVATE *psf, void *ptr, int bytes) 865{ int count = 0 ; 866 867 if (psf->header.indx + bytes >= psf->header.len && psf_bump_header_allocation (psf, bytes)) 868 return count ; 869 870 if (psf->header.indx + bytes > psf->header.end) 871 { count = psf_fread (psf->header.ptr + psf->header.end, 1, bytes - (psf->header.end - psf->header.indx), psf) ; 872 if (count != bytes - (int) (psf->header.end - psf->header.indx)) 873 { psf_log_printf (psf, "Error : psf_fread returned short count.\n") ; 874 return count ; 875 } ; 876 psf->header.end += count ; 877 } ; 878 879 memcpy (ptr, psf->header.ptr + psf->header.indx, bytes) ; 880 psf->header.indx += bytes ; 881 882 return bytes ; 883} /* header_read */ 884 885static void 886header_seek (SF_PRIVATE *psf, sf_count_t position, int whence) 887{ 888 switch (whence) 889 { case SEEK_SET : 890 if (psf->header.indx + position >= psf->header.len) 891 psf_bump_header_allocation (psf, position) ; 892 if (position > psf->header.len) 893 { /* Too much header to cache so just seek instead. */ 894 psf->header.indx = psf->header.end = 0 ; 895 psf_fseek (psf, position, whence) ; 896 return ; 897 } ; 898 if (position > psf->header.end) 899 psf->header.end += psf_fread (psf->header.ptr + psf->header.end, 1, position - psf->header.end, psf) ; 900 psf->header.indx = position ; 901 break ; 902 903 case SEEK_CUR : 904 if (psf->header.indx + position >= psf->header.len) 905 psf_bump_header_allocation (psf, position) ; 906 907 if (psf->header.indx + position < 0) 908 break ; 909 910 if (psf->header.indx >= psf->header.len) 911 { psf_fseek (psf, position, whence) ; 912 return ; 913 } ; 914 915 if (psf->header.indx + position <= psf->header.end) 916 { psf->header.indx += position ; 917 break ; 918 } ; 919 920 if (psf->header.indx + position > psf->header.len) 921 { /* Need to jump this without caching it. */ 922 position -= (psf->header.end - psf->header.indx) ; 923 psf->header.indx = psf->header.end ; 924 if (psf->is_pipe) 925 { 926 /* seeking is not supported on pipe input, so we read instead */ 927 size_t skip = position ; 928 while (skip) 929 { char junk [16 * 1024] ; 930 size_t to_skip = SF_MIN (skip, sizeof (junk)) ; 931 psf_fread (junk, 1, to_skip, psf) ; 932 skip -= to_skip ; 933 } 934 } 935 else 936 { psf_fseek (psf, position, SEEK_CUR) ; 937 } 938 break ; 939 } ; 940 941 psf->header.end += psf_fread (psf->header.ptr + psf->header.end, 1, position - (psf->header.end - psf->header.indx), psf) ; 942 psf->header.indx = psf->header.end ; 943 break ; 944 945 case SEEK_END : 946 default : 947 psf_log_printf (psf, "Bad whence param in header_seek().\n") ; 948 break ; 949 } ; 950 951 return ; 952} /* header_seek */ 953 954static int 955header_gets (SF_PRIVATE *psf, char *ptr, int bufsize) 956{ int k ; 957 958 if (psf->header.indx + bufsize >= psf->header.len && psf_bump_header_allocation (psf, bufsize)) 959 return 0 ; 960 961 for (k = 0 ; k < bufsize - 1 ; k++) 962 { if (psf->header.indx < psf->header.end) 963 { ptr [k] = psf->header.ptr [psf->header.indx] ; 964 psf->header.indx ++ ; 965 } 966 else 967 { psf->header.end += psf_fread (psf->header.ptr + psf->header.end, 1, 1, psf) ; 968 ptr [k] = psf->header.ptr [psf->header.indx] ; 969 psf->header.indx = psf->header.end ; 970 } ; 971 972 if (ptr [k] == '\n') 973 break ; 974 } ; 975 976 ptr [k] = 0 ; 977 978 return k ; 979} /* header_gets */ 980 981int 982psf_binheader_readf (SF_PRIVATE *psf, char const *format, ...) 983{ va_list argptr ; 984 sf_count_t *countptr, countdata ; 985 unsigned char *ucptr, sixteen_bytes [16] = { 0 } ; 986 unsigned int *intptr, intdata ; 987 unsigned short *shortptr ; 988 char *charptr ; 989 float *floatptr ; 990 double *doubleptr ; 991 char c ; 992 int byte_count = 0, count = 0 ; 993 994 if (! format) 995 return psf_ftell (psf) ; 996 997 va_start (argptr, format) ; 998 999 while ((c = *format++)) 1000 { 1001 if (psf->header.indx + 16 >= psf->header.len && psf_bump_header_allocation (psf, 16)) 1002 break ; 1003 1004 switch (c) 1005 { case 'e' : /* All conversions are now from LE to host. */ 1006 psf->rwf_endian = SF_ENDIAN_LITTLE ; 1007 break ; 1008 1009 case 'E' : /* All conversions are now from BE to host. */ 1010 psf->rwf_endian = SF_ENDIAN_BIG ; 1011 break ; 1012 1013 case 'm' : /* 4 byte marker value eg 'RIFF' */ 1014 intptr = va_arg (argptr, unsigned int*) ; 1015 *intptr = 0 ; 1016 ucptr = (unsigned char*) intptr ; 1017 byte_count += header_read (psf, ucptr, sizeof (int)) ; 1018 *intptr = GET_MARKER (ucptr) ; 1019 break ; 1020 1021 case 'h' : 1022 intptr = va_arg (argptr, unsigned int*) ; 1023 *intptr = 0 ; 1024 ucptr = (unsigned char*) intptr ; 1025 byte_count += header_read (psf, sixteen_bytes, sizeof (sixteen_bytes)) ; 1026 { int k ; 1027 intdata = 0 ; 1028 for (k = 0 ; k < 16 ; k++) 1029 intdata ^= sixteen_bytes [k] << k ; 1030 } 1031 *intptr = intdata ; 1032 break ; 1033 1034 case '1' : 1035 charptr = va_arg (argptr, char*) ; 1036 *charptr = 0 ; 1037 byte_count += header_read (psf, charptr, sizeof (char)) ; 1038 break ; 1039 1040 case '2' : /* 2 byte value with the current endian-ness */ 1041 shortptr = va_arg (argptr, unsigned short*) ; 1042 *shortptr = 0 ; 1043 ucptr = (unsigned char*) shortptr ; 1044 byte_count += header_read (psf, ucptr, sizeof (short)) ; 1045 if (psf->rwf_endian == SF_ENDIAN_BIG) 1046 *shortptr = GET_BE_SHORT (ucptr) ; 1047 else 1048 *shortptr = GET_LE_SHORT (ucptr) ; 1049 break ; 1050 1051 case '3' : /* 3 byte value with the current endian-ness */ 1052 intptr = va_arg (argptr, unsigned int*) ; 1053 *intptr = 0 ; 1054 byte_count += header_read (psf, sixteen_bytes, 3) ; 1055 if (psf->rwf_endian == SF_ENDIAN_BIG) 1056 *intptr = GET_BE_3BYTE (sixteen_bytes) ; 1057 else 1058 *intptr = GET_LE_3BYTE (sixteen_bytes) ; 1059 break ; 1060 1061 case '4' : /* 4 byte value with the current endian-ness */ 1062 intptr = va_arg (argptr, unsigned int*) ; 1063 *intptr = 0 ; 1064 ucptr = (unsigned char*) intptr ; 1065 byte_count += header_read (psf, ucptr, sizeof (int)) ; 1066 if (psf->rwf_endian == SF_ENDIAN_BIG) 1067 *intptr = psf_get_be32 (ucptr, 0) ; 1068 else 1069 *intptr = psf_get_le32 (ucptr, 0) ; 1070 break ; 1071 1072 case '8' : /* 8 byte value with the current endian-ness */ 1073 countptr = va_arg (argptr, sf_count_t *) ; 1074 *countptr = 0 ; 1075 byte_count += header_read (psf, sixteen_bytes, 8) ; 1076 if (psf->rwf_endian == SF_ENDIAN_BIG) 1077 countdata = psf_get_be64 (sixteen_bytes, 0) ; 1078 else 1079 countdata = psf_get_le64 (sixteen_bytes, 0) ; 1080 *countptr = countdata ; 1081 break ; 1082 1083 case 'f' : /* Float conversion */ 1084 floatptr = va_arg (argptr, float *) ; 1085 *floatptr = 0.0 ; 1086 byte_count += header_read (psf, floatptr, sizeof (float)) ; 1087 if (psf->rwf_endian == SF_ENDIAN_BIG) 1088 *floatptr = float32_be_read ((unsigned char*) floatptr) ; 1089 else 1090 *floatptr = float32_le_read ((unsigned char*) floatptr) ; 1091 break ; 1092 1093 case 'd' : /* double conversion */ 1094 doubleptr = va_arg (argptr, double *) ; 1095 *doubleptr = 0.0 ; 1096 byte_count += header_read (psf, doubleptr, sizeof (double)) ; 1097 if (psf->rwf_endian == SF_ENDIAN_BIG) 1098 *doubleptr = double64_be_read ((unsigned char*) doubleptr) ; 1099 else 1100 *doubleptr = double64_le_read ((unsigned char*) doubleptr) ; 1101 break ; 1102 1103 case 's' : 1104 psf_log_printf (psf, "Format conversion 's' not implemented yet.\n") ; 1105 /* 1106 strptr = va_arg (argptr, char *) ; 1107 size = strlen (strptr) + 1 ; 1108 size += (size & 1) ; 1109 longdata = H2LE_32 (size) ; 1110 get_int (psf, longdata) ; 1111 memcpy (&(psf->header.ptr [psf->header.indx]), strptr, size) ; 1112 psf->header.indx += size ; 1113 */ 1114 break ; 1115 1116 case 'b' : /* Raw bytes */ 1117 charptr = va_arg (argptr, char*) ; 1118 count = va_arg (argptr, size_t) ; 1119 memset (charptr, 0, count) ; 1120 byte_count += header_read (psf, charptr, count) ; 1121 break ; 1122 1123 case 'G' : 1124 charptr = va_arg (argptr, char*) ; 1125 count = va_arg (argptr, size_t) ; 1126 memset (charptr, 0, count) ; 1127 1128 if (psf->header.indx + count >= psf->header.len && psf_bump_header_allocation (psf, count)) 1129 break ; 1130 1131 byte_count += header_gets (psf, charptr, count) ; 1132 break ; 1133 1134 case 'z' : 1135 psf_log_printf (psf, "Format conversion 'z' not implemented yet.\n") ; 1136 /* 1137 size = va_arg (argptr, size_t) ; 1138 while (size) 1139 { psf->header.ptr [psf->header.indx] = 0 ; 1140 psf->header.indx ++ ; 1141 size -- ; 1142 } ; 1143 */ 1144 break ; 1145 1146 case 'p' : /* Seek to position from start. */ 1147 count = va_arg (argptr, size_t) ; 1148 header_seek (psf, count, SEEK_SET) ; 1149 byte_count = count ; 1150 break ; 1151 1152 case 'j' : /* Seek to position from current position. */ 1153 count = va_arg (argptr, size_t) ; 1154 header_seek (psf, count, SEEK_CUR) ; 1155 byte_count += count ; 1156 break ; 1157 1158 case '!' : /* Clear buffer, forcing re-read. */ 1159 psf->header.end = psf->header.indx = 0 ; 1160 break ; 1161 1162 default : 1163 psf_log_printf (psf, "*** Invalid format specifier `%c'\n", c) ; 1164 psf->error = SFE_INTERNAL ; 1165 break ; 1166 } ; 1167 } ; 1168 1169 va_end (argptr) ; 1170 1171 return byte_count ; 1172} /* psf_binheader_readf */ 1173 1174/*----------------------------------------------------------------------------------------------- 1175*/ 1176 1177sf_count_t 1178psf_default_seek (SF_PRIVATE *psf, int UNUSED (mode), sf_count_t samples_from_start) 1179{ sf_count_t position, retval ; 1180 1181 if (! (psf->blockwidth && psf->dataoffset >= 0)) 1182 { psf->error = SFE_BAD_SEEK ; 1183 return PSF_SEEK_ERROR ; 1184 } ; 1185 1186 if (! psf->sf.seekable) 1187 { psf->error = SFE_NOT_SEEKABLE ; 1188 return PSF_SEEK_ERROR ; 1189 } ; 1190 1191 position = psf->dataoffset + psf->blockwidth * samples_from_start ; 1192 1193 if ((retval = psf_fseek (psf, position, SEEK_SET)) != position) 1194 { psf->error = SFE_SEEK_FAILED ; 1195 return PSF_SEEK_ERROR ; 1196 } ; 1197 1198 return samples_from_start ; 1199} /* psf_default_seek */ 1200 1201/*----------------------------------------------------------------------------------------------- 1202*/ 1203 1204void 1205psf_hexdump (const void *ptr, int len) 1206{ const char *data ; 1207 char ascii [17] ; 1208 int k, m ; 1209 1210 if ((data = ptr) == NULL) 1211 return ; 1212 if (len <= 0) 1213 return ; 1214 1215 puts ("") ; 1216 for (k = 0 ; k < len ; k += 16) 1217 { memset (ascii, ' ', sizeof (ascii)) ; 1218 1219 printf ("%08X: ", k) ; 1220 for (m = 0 ; m < 16 && k + m < len ; m++) 1221 { printf (m == 8 ? " %02X " : "%02X ", data [k + m] & 0xFF) ; 1222 ascii [m] = psf_isprint (data [k + m]) ? data [k + m] : '.' ; 1223 } ; 1224 1225 if (m <= 8) printf (" ") ; 1226 for ( ; m < 16 ; m++) printf (" ") ; 1227 1228 ascii [16] = 0 ; 1229 printf (" %s\n", ascii) ; 1230 } ; 1231 1232 puts ("") ; 1233} /* psf_hexdump */ 1234 1235void 1236psf_log_SF_INFO (SF_PRIVATE *psf) 1237{ psf_log_printf (psf, "---------------------------------\n") ; 1238 1239 psf_log_printf (psf, " Sample rate : %d\n", psf->sf.samplerate) ; 1240 if (psf->sf.frames == SF_COUNT_MAX) 1241 psf_log_printf (psf, " Frames : unknown\n") ; 1242 else 1243 psf_log_printf (psf, " Frames : %D\n", psf->sf.frames) ; 1244 psf_log_printf (psf, " Channels : %d\n", psf->sf.channels) ; 1245 1246 psf_log_printf (psf, " Format : 0x%X\n", psf->sf.format) ; 1247 psf_log_printf (psf, " Sections : %d\n", psf->sf.sections) ; 1248 psf_log_printf (psf, " Seekable : %s\n", psf->sf.seekable ? "TRUE" : "FALSE") ; 1249 1250 psf_log_printf (psf, "---------------------------------\n") ; 1251} /* psf_dump_SFINFO */ 1252 1253/*======================================================================================== 1254*/ 1255 1256int 1257psf_isprint (int ch) 1258{ return (ch >= ' ' && ch <= '~') ; 1259} /* psf_isprint */ 1260 1261void 1262psf_strlcat (char *dest, size_t n, const char *src) 1263{ strncat (dest, src, n - strlen (dest) - 1) ; 1264 dest [n - 1] = 0 ; 1265} /* psf_strlcat */ 1266 1267void 1268psf_strlcpy (char *dest, size_t n, const char *src) 1269{ strncpy (dest, src, n - 1) ; 1270 dest [n - 1] = 0 ; 1271} /* psf_strlcpy */ 1272 1273/*======================================================================================== 1274*/ 1275 1276void * 1277psf_memdup (const void *src, size_t n) 1278{ if (src == NULL) 1279 return NULL ; 1280 1281 void * mem = calloc (1, n & 3 ? n + 4 - (n & 3) : n) ; 1282 if (mem != NULL) 1283 memcpy (mem, src, n) ; 1284 return mem ; 1285} /* psf_memdup */ 1286 1287void* 1288psf_memset (void *s, int c, sf_count_t len) 1289{ char *ptr ; 1290 int setcount ; 1291 1292 ptr = (char *) s ; 1293 1294 while (len > 0) 1295 { setcount = (len > 0x10000000) ? 0x10000000 : (int) len ; 1296 1297 memset (ptr, c, setcount) ; 1298 1299 ptr += setcount ; 1300 len -= setcount ; 1301 } ; 1302 1303 return s ; 1304} /* psf_memset */ 1305 1306 1307/* 1308** Clang refuses to do sizeof (SF_CUES_VAR (cue_count)) so we have to manually 1309** bodgy something up instead. 1310*/ 1311 1312#ifdef _MSC_VER 1313typedef SF_CUES_VAR (0) SF_CUES_0 ; 1314#else 1315typedef SF_CUES_VAR () SF_CUES_0 ; 1316#endif 1317 1318/* calculate size of SF_CUES struct given number of cues */ 1319#define SF_CUES_VAR_SIZE(count) (sizeof (SF_CUES_0) + count * sizeof (SF_CUE_POINT)) 1320 1321/* calculate number of cues in SF_CUES struct given data size */ 1322#define SF_CUES_COUNT(datasize) (((datasize) - sizeof (uint32_t)) / sizeof (SF_CUE_POINT)) 1323 1324SF_CUES * 1325psf_cues_alloc (uint32_t cue_count) 1326{ SF_CUES *pcues = calloc (1, SF_CUES_VAR_SIZE (cue_count)) ; 1327 if (pcues) 1328 { pcues->cue_count = cue_count ; 1329 } ; 1330 return pcues ; 1331} /* psf_cues_alloc */ 1332 1333SF_CUES * 1334psf_cues_dup (const void * ptr, size_t datasize) 1335{ const SF_CUES *pcues = ptr ; 1336 SF_CUES *pnew = NULL ; 1337 1338 if (pcues->cue_count <= SF_CUES_COUNT (datasize)) 1339 { /* check that passed-in datasize is consistent with cue_count in passed-in SF_CUES struct */ 1340 pnew = psf_cues_alloc (pcues->cue_count) ; 1341 memcpy (pnew, pcues, SF_CUES_VAR_SIZE (pcues->cue_count)) ; 1342 } 1343 1344 return pnew ; 1345} /* psf_cues_dup */ 1346 1347void 1348psf_get_cues (SF_PRIVATE * psf, void * data, size_t datasize) 1349{ 1350 if (psf->cues) 1351 { uint32_t cue_count = SF_CUES_COUNT (datasize) ; 1352 1353 cue_count = SF_MIN (cue_count, psf->cues->cue_count) ; 1354 memcpy (data, psf->cues, SF_CUES_VAR_SIZE (cue_count)) ; 1355 ((SF_CUES*) data)->cue_count = cue_count ; 1356 } ; 1357 1358 return ; 1359} /* psf_get_cues */ 1360 1361 1362SF_INSTRUMENT * 1363psf_instrument_alloc (void) 1364{ SF_INSTRUMENT *instr ; 1365 1366 instr = calloc (1, sizeof (SF_INSTRUMENT)) ; 1367 1368 if (instr == NULL) 1369 return NULL ; 1370 1371 /* Set non-zero default values. */ 1372 instr->basenote = -1 ; 1373 instr->velocity_lo = -1 ; 1374 instr->velocity_hi = -1 ; 1375 instr->key_lo = -1 ; 1376 instr->key_hi = -1 ; 1377 1378 return instr ; 1379} /* psf_instrument_alloc */ 1380 1381void 1382psf_sanitize_string (char * cptr, int len) 1383{ 1384 do 1385 { 1386 len -- ; 1387 cptr [len] = psf_isprint (cptr [len]) ? cptr [len] : '.' ; 1388 } 1389 while (len > 0) ; 1390} /* psf_sanitize_string */ 1391 1392void 1393psf_get_date_str (char *str, int maxlen) 1394{ time_t current ; 1395 struct tm timedata, *tmptr ; 1396 1397 time (¤t) ; 1398 1399#if defined (HAVE_GMTIME_R) 1400 /* If the re-entrant version is available, use it. */ 1401 tmptr = gmtime_r (¤t, &timedata) ; 1402#elif defined (HAVE_GMTIME) 1403 /* Otherwise use the standard one and copy the data to local storage. */ 1404 tmptr = gmtime (¤t) ; 1405 memcpy (&timedata, tmptr, sizeof (timedata)) ; 1406#else 1407 tmptr = NULL ; 1408#endif 1409 1410 if (tmptr) 1411 snprintf (str, maxlen, "%4d-%02d-%02d %02d:%02d:%02d UTC", 1412 1900 + timedata.tm_year, timedata.tm_mon, timedata.tm_mday, 1413 timedata.tm_hour, timedata.tm_min, timedata.tm_sec) ; 1414 else 1415 snprintf (str, maxlen, "Unknown date") ; 1416 1417 return ; 1418} /* psf_get_date_str */ 1419 1420int 1421subformat_to_bytewidth (int format) 1422{ 1423 switch (format) 1424 { case SF_FORMAT_PCM_U8 : 1425 case SF_FORMAT_PCM_S8 : 1426 return 1 ; 1427 case SF_FORMAT_PCM_16 : 1428 return 2 ; 1429 case SF_FORMAT_PCM_24 : 1430 return 3 ; 1431 case SF_FORMAT_PCM_32 : 1432 case SF_FORMAT_FLOAT : 1433 return 4 ; 1434 case SF_FORMAT_DOUBLE : 1435 return 8 ; 1436 } ; 1437 1438 return 0 ; 1439} /* subformat_to_bytewidth */ 1440 1441int 1442s_bitwidth_to_subformat (int bits) 1443{ static int array [] = 1444 { SF_FORMAT_PCM_S8, SF_FORMAT_PCM_16, SF_FORMAT_PCM_24, SF_FORMAT_PCM_32 1445 } ; 1446 1447 if (bits < 8 || bits > 32) 1448 return 0 ; 1449 1450 return array [((bits + 7) / 8) - 1] ; 1451} /* bitwidth_to_subformat */ 1452 1453int 1454u_bitwidth_to_subformat (int bits) 1455{ static int array [] = 1456 { SF_FORMAT_PCM_U8, SF_FORMAT_PCM_16, SF_FORMAT_PCM_24, SF_FORMAT_PCM_32 1457 } ; 1458 1459 if (bits < 8 || bits > 32) 1460 return 0 ; 1461 1462 return array [((bits + 7) / 8) - 1] ; 1463} /* bitwidth_to_subformat */ 1464 1465/* 1466** psf_rand_int32 : Not crypto quality, but more than adequate for things 1467** like stream serial numbers in Ogg files or the unique_id field of the 1468** SF_PRIVATE struct. 1469*/ 1470 1471int32_t 1472psf_rand_int32 (void) 1473{ static uint64_t value = 0 ; 1474 int k, count ; 1475 1476 if (value == 0) 1477 { 1478#if HAVE_GETTIMEOFDAY 1479 struct timeval tv ; 1480 gettimeofday (&tv, NULL) ; 1481 value = tv.tv_sec + tv.tv_usec ; 1482#else 1483 value = time (NULL) ; 1484#endif 1485 } ; 1486 1487 count = 4 + (value & 7) ; 1488 for (k = 0 ; k < count ; k++) 1489 value = (11117 * value + 211231) & 0x7fffffff ; 1490 1491 return (int32_t) value ; 1492} /* psf_rand_int32 */ 1493 1494void 1495append_snprintf (char * dest, size_t maxlen, const char * fmt, ...) 1496{ size_t len = strlen (dest) ; 1497 1498 if (len < maxlen) 1499 { va_list ap ; 1500 1501 va_start (ap, fmt) ; 1502 vsnprintf (dest + len, maxlen - len, fmt, ap) ; 1503 va_end (ap) ; 1504 } ; 1505 1506 return ; 1507} /* append_snprintf */ 1508 1509 1510void 1511psf_strlcpy_crlf (char *dest, const char *src, size_t destmax, size_t srcmax) 1512{ /* Must be minus 2 so it can still expand a single trailing '\n' or '\r'. */ 1513 char * destend = dest + destmax - 2 ; 1514 const char * srcend = src + srcmax ; 1515 1516 while (dest < destend && src < srcend) 1517 { if ((src [0] == '\r' && src [1] == '\n') || (src [0] == '\n' && src [1] == '\r')) 1518 { *dest++ = '\r' ; 1519 *dest++ = '\n' ; 1520 src += 2 ; 1521 continue ; 1522 } ; 1523 1524 if (src [0] == '\r') 1525 { *dest++ = '\r' ; 1526 *dest++ = '\n' ; 1527 src += 1 ; 1528 continue ; 1529 } ; 1530 1531 if (src [0] == '\n') 1532 { *dest++ = '\r' ; 1533 *dest++ = '\n' ; 1534 src += 1 ; 1535 continue ; 1536 } ; 1537 1538 *dest++ = *src++ ; 1539 } ; 1540 1541 /* Make sure dest is terminated. */ 1542 *dest = 0 ; 1543} /* psf_strlcpy_crlf */ 1544 1545sf_count_t 1546psf_decode_frame_count (SF_PRIVATE *psf) 1547{ sf_count_t count, readlen, total = 0 ; 1548 BUF_UNION ubuf ; 1549 1550 /* If we're reading from a pipe or the file is too long, just return SF_COUNT_MAX. */ 1551 if (psf_is_pipe (psf) || psf->datalength > 0x1000000) 1552 return SF_COUNT_MAX ; 1553 1554 psf_fseek (psf, psf->dataoffset, SEEK_SET) ; 1555 1556 readlen = ARRAY_LEN (ubuf.ibuf) / psf->sf.channels ; 1557 readlen *= psf->sf.channels ; 1558 1559 while ((count = psf->read_int (psf, ubuf.ibuf, readlen)) > 0) 1560 total += count ; 1561 1562 psf_fseek (psf, psf->dataoffset, SEEK_SET) ; 1563 1564 return total / psf->sf.channels ; 1565} /* psf_decode_frame_count */ 1566 1567/*============================================================================== 1568*/ 1569 1570#define CASE_NAME(x) case x : return #x ; break ; 1571 1572const char * 1573str_of_major_format (int format) 1574{ switch (SF_CONTAINER (format)) 1575 { CASE_NAME (SF_FORMAT_WAV) ; 1576 CASE_NAME (SF_FORMAT_AIFF) ; 1577 CASE_NAME (SF_FORMAT_AU) ; 1578 CASE_NAME (SF_FORMAT_RAW) ; 1579 CASE_NAME (SF_FORMAT_PAF) ; 1580 CASE_NAME (SF_FORMAT_SVX) ; 1581 CASE_NAME (SF_FORMAT_NIST) ; 1582 CASE_NAME (SF_FORMAT_VOC) ; 1583 CASE_NAME (SF_FORMAT_IRCAM) ; 1584 CASE_NAME (SF_FORMAT_W64) ; 1585 CASE_NAME (SF_FORMAT_MAT4) ; 1586 CASE_NAME (SF_FORMAT_MAT5) ; 1587 CASE_NAME (SF_FORMAT_PVF) ; 1588 CASE_NAME (SF_FORMAT_XI) ; 1589 CASE_NAME (SF_FORMAT_HTK) ; 1590 CASE_NAME (SF_FORMAT_SDS) ; 1591 CASE_NAME (SF_FORMAT_AVR) ; 1592 CASE_NAME (SF_FORMAT_WAVEX) ; 1593 CASE_NAME (SF_FORMAT_SD2) ; 1594 CASE_NAME (SF_FORMAT_FLAC) ; 1595 CASE_NAME (SF_FORMAT_CAF) ; 1596 CASE_NAME (SF_FORMAT_WVE) ; 1597 CASE_NAME (SF_FORMAT_OGG) ; 1598 CASE_NAME (SF_FORMAT_MPEG) ; 1599 default : 1600 break ; 1601 } ; 1602 1603 return "BAD_MAJOR_FORMAT" ; 1604} /* str_of_major_format */ 1605 1606const char * 1607str_of_minor_format (int format) 1608{ switch (SF_CODEC (format)) 1609 { CASE_NAME (SF_FORMAT_PCM_S8) ; 1610 CASE_NAME (SF_FORMAT_PCM_16) ; 1611 CASE_NAME (SF_FORMAT_PCM_24) ; 1612 CASE_NAME (SF_FORMAT_PCM_32) ; 1613 CASE_NAME (SF_FORMAT_PCM_U8) ; 1614 CASE_NAME (SF_FORMAT_FLOAT) ; 1615 CASE_NAME (SF_FORMAT_DOUBLE) ; 1616 CASE_NAME (SF_FORMAT_ULAW) ; 1617 CASE_NAME (SF_FORMAT_ALAW) ; 1618 CASE_NAME (SF_FORMAT_IMA_ADPCM) ; 1619 CASE_NAME (SF_FORMAT_MS_ADPCM) ; 1620 CASE_NAME (SF_FORMAT_GSM610) ; 1621 CASE_NAME (SF_FORMAT_VOX_ADPCM) ; 1622 CASE_NAME (SF_FORMAT_NMS_ADPCM_16) ; 1623 CASE_NAME (SF_FORMAT_NMS_ADPCM_24) ; 1624 CASE_NAME (SF_FORMAT_NMS_ADPCM_32) ; 1625 CASE_NAME (SF_FORMAT_G721_32) ; 1626 CASE_NAME (SF_FORMAT_G723_24) ; 1627 CASE_NAME (SF_FORMAT_G723_40) ; 1628 CASE_NAME (SF_FORMAT_DWVW_12) ; 1629 CASE_NAME (SF_FORMAT_DWVW_16) ; 1630 CASE_NAME (SF_FORMAT_DWVW_24) ; 1631 CASE_NAME (SF_FORMAT_DWVW_N) ; 1632 CASE_NAME (SF_FORMAT_DPCM_8) ; 1633 CASE_NAME (SF_FORMAT_DPCM_16) ; 1634 CASE_NAME (SF_FORMAT_VORBIS) ; 1635 CASE_NAME (SF_FORMAT_MPEG_LAYER_I) ; 1636 CASE_NAME (SF_FORMAT_MPEG_LAYER_II) ; 1637 CASE_NAME (SF_FORMAT_MPEG_LAYER_III) ; 1638 default : 1639 break ; 1640 } ; 1641 1642 return "BAD_MINOR_FORMAT" ; 1643} /* str_of_minor_format */ 1644 1645const char * 1646str_of_open_mode (int mode) 1647{ switch (mode) 1648 { CASE_NAME (SFM_READ) ; 1649 CASE_NAME (SFM_WRITE) ; 1650 CASE_NAME (SFM_RDWR) ; 1651 1652 default : 1653 break ; 1654 } ; 1655 1656 return "BAD_MODE" ; 1657} /* str_of_open_mode */ 1658 1659const char * 1660str_of_endianness (int end) 1661{ switch (end) 1662 { CASE_NAME (SF_ENDIAN_BIG) ; 1663 CASE_NAME (SF_ENDIAN_LITTLE) ; 1664 CASE_NAME (SF_ENDIAN_CPU) ; 1665 default : 1666 break ; 1667 } ; 1668 1669 /* Zero length string for SF_ENDIAN_FILE. */ 1670 return "" ; 1671} /* str_of_endianness */ 1672 1673/*============================================================================== 1674*/ 1675 1676void 1677psf_f2s_array (const float *src, short *dest, int count, int normalize) 1678{ float normfact ; 1679 1680 normfact = normalize ? (1.0 * 0x7FFF) : 1.0 ; 1681 for (int i = 0 ; i < count ; i++) 1682 dest [i] = psf_lrintf (src [i] * normfact) ; 1683 1684 return ; 1685} /* psf_f2s_array */ 1686 1687void 1688psf_f2s_clip_array (const float *src, short *dest, int count, int normalize) 1689{ float normfact, scaled_value ; 1690 1691 normfact = normalize ? (1.0 * 0x8000) : 1.0 ; 1692 1693 for (int i = 0 ; i < count ; i++) 1694 { scaled_value = src [i] * normfact ; 1695 if (scaled_value >= (1.0 * 0x7FFF)) 1696 { dest [i] = 0x7FFF ; 1697 continue ; 1698 } ; 1699 if (scaled_value <= (-8.0 * 0x1000)) 1700 { dest [i] = -0x7FFF - 1 ; 1701 continue ; 1702 } ; 1703 1704 dest [i] = psf_lrintf (scaled_value) ; 1705 } ; 1706 1707 return ; 1708} /* psf_f2s_clip_array */ 1709 1710void 1711psf_d2s_array (const double *src, short *dest, int count, int normalize) 1712{ double normfact ; 1713 1714 normfact = normalize ? (1.0 * 0x7FFF) : 1.0 ; 1715 for (int i = 0 ; i < count ; i++) 1716 dest [i] = psf_lrint (src [i] * normfact) ; 1717 1718 return ; 1719} /* psf_f2s_array */ 1720 1721void 1722psf_d2s_clip_array (const double *src, short *dest, int count, int normalize) 1723{ double normfact, scaled_value ; 1724 1725 normfact = normalize ? (1.0 * 0x8000) : 1.0 ; 1726 1727 for (int i = 0 ; i < count ; i++) 1728 { scaled_value = src [i] * normfact ; 1729 if (scaled_value >= (1.0 * 0x7FFF)) 1730 { dest [i] = 0x7FFF ; 1731 continue ; 1732 } ; 1733 if (scaled_value <= (-8.0 * 0x1000)) 1734 { dest [i] = -0x7FFF - 1 ; 1735 continue ; 1736 } ; 1737 1738 dest [i] = psf_lrint (scaled_value) ; 1739 } ; 1740 1741 return ; 1742} /* psf_d2s_clip_array */ 1743 1744 1745void 1746psf_f2i_array (const float *src, int *dest, int count, int normalize) 1747{ float normfact ; 1748 1749 normfact = normalize ? (1.0 * 0x7FFFFFFF) : 1.0 ; 1750 for (int i = 0 ; i < count ; i++) 1751 dest [i] = psf_lrintf (src [i] * normfact) ; 1752 1753 return ; 1754} /* psf_f2i_array */ 1755 1756void 1757psf_f2i_clip_array (const float *src, int *dest, int count, int normalize) 1758{ float normfact, scaled_value ; 1759 1760 normfact = normalize ? (8.0 * 0x10000000) : 1.0 ; 1761 1762 for (int i = 0 ; i < count ; i++) 1763 { scaled_value = src [i] * normfact ; 1764#if CPU_CLIPS_POSITIVE == 0 1765 if (scaled_value >= (1.0 * 0x7FFFFFFF)) 1766 { dest [i] = 0x7FFFFFFF ; 1767 continue ; 1768 } ; 1769#endif 1770#if CPU_CLIPS_NEGATIVE == 0 1771 if (scaled_value <= (-8.0 * 0x10000000)) 1772 { dest [i] = 0x80000000 ; 1773 continue ; 1774 } ; 1775#endif 1776 1777 dest [i] = psf_lrintf (scaled_value) ; 1778 } ; 1779 1780 return ; 1781} /* psf_f2i_clip_array */ 1782 1783void 1784psf_d2i_array (const double *src, int *dest, int count, int normalize) 1785{ double normfact ; 1786 1787 normfact = normalize ? (1.0 * 0x7FFFFFFF) : 1.0 ; 1788 for (int i = 0 ; i < count ; i++) 1789 dest [i] = psf_lrint (src [i] * normfact) ; 1790 1791 return ; 1792} /* psf_f2i_array */ 1793 1794void 1795psf_d2i_clip_array (const double *src, int *dest, int count, int normalize) 1796{ double normfact, scaled_value ; 1797 1798 normfact = normalize ? (8.0 * 0x10000000) : 1.0 ; 1799 1800 for (int i = 0 ; i < count ; i++) 1801 { scaled_value = src [i] * normfact ; 1802#if CPU_CLIPS_POSITIVE == 0 1803 if (scaled_value >= (1.0 * 0x7FFFFFFF)) 1804 { dest [i] = 0x7FFFFFFF ; 1805 continue ; 1806 } ; 1807#endif 1808#if CPU_CLIPS_NEGATIVE == 0 1809 if (scaled_value <= (-8.0 * 0x10000000)) 1810 { dest [i] = 0x80000000 ; 1811 continue ; 1812 } ; 1813#endif 1814 1815 dest [i] = psf_lrint (scaled_value) ; 1816 } ; 1817 1818 return ; 1819} /* psf_d2i_clip_array */ 1820 1821FILE * 1822psf_open_tmpfile (char * fname, size_t fnamelen) 1823{ const char * tmpdir ; 1824 FILE * file ; 1825 1826 if (OS_IS_WIN32) 1827 tmpdir = getenv ("TEMP") ; 1828 else 1829 { tmpdir = getenv ("TMPDIR") ; 1830 tmpdir = tmpdir == NULL ? "/tmp" : tmpdir ; 1831 } ; 1832 1833 if (tmpdir && access (tmpdir, R_OK | W_OK | X_OK) == 0) 1834 { snprintf (fname, fnamelen, "%s/%x%x-alac.tmp", tmpdir, psf_rand_int32 (), psf_rand_int32 ()) ; 1835 if ((file = fopen (fname, "wb+")) != NULL) 1836 return file ; 1837 } ; 1838 1839 snprintf (fname, fnamelen, "%x%x-alac.tmp", psf_rand_int32 (), psf_rand_int32 ()) ; 1840 if ((file = fopen (fname, "wb+")) != NULL) 1841 return file ; 1842 1843 memset (fname, 0, fnamelen) ; 1844 return NULL ; 1845} /* psf_open_tmpfile */ 1846