1/* 2** Copyright (C) 1999-2017 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 "sfconfig.h" 20 21#include <stdio.h> 22#include <stdlib.h> 23#include <string.h> 24#include <limits.h> 25#include <math.h> 26 27#include "sndfile.h" 28#include "sfendian.h" 29#include "common.h" 30 31#if CPU_IS_LITTLE_ENDIAN 32 #define FLOAT32_READ float32_le_read 33 #define FLOAT32_WRITE float32_le_write 34#elif CPU_IS_BIG_ENDIAN 35 #define FLOAT32_READ float32_be_read 36 #define FLOAT32_WRITE float32_be_write 37#endif 38 39/*-------------------------------------------------------------------------------------------- 40** Processor floating point capabilities. float32_get_capability () returns one of the 41** latter four values. 42*/ 43 44enum 45{ FLOAT_UNKNOWN = 0x00, 46 FLOAT_CAN_RW_LE = 0x12, 47 FLOAT_CAN_RW_BE = 0x23, 48 FLOAT_BROKEN_LE = 0x34, 49 FLOAT_BROKEN_BE = 0x45 50} ; 51 52/*-------------------------------------------------------------------------------------------- 53** Prototypes for private functions. 54*/ 55 56static sf_count_t host_read_f2s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ; 57static sf_count_t host_read_f2i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ; 58static sf_count_t host_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ; 59static sf_count_t host_read_f2d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ; 60 61static sf_count_t host_write_s2f (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ; 62static sf_count_t host_write_i2f (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ; 63static sf_count_t host_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ; 64static sf_count_t host_write_d2f (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ; 65 66static void float32_peak_update (SF_PRIVATE *psf, const float *buffer, int count, sf_count_t indx) ; 67 68static sf_count_t replace_read_f2s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ; 69static sf_count_t replace_read_f2i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ; 70static sf_count_t replace_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ; 71static sf_count_t replace_read_f2d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ; 72 73static sf_count_t replace_write_s2f (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ; 74static sf_count_t replace_write_i2f (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ; 75static sf_count_t replace_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ; 76static sf_count_t replace_write_d2f (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ; 77 78static void bf2f_array (float *buffer, int count) ; 79static void f2bf_array (float *buffer, int count) ; 80 81static int float32_get_capability (SF_PRIVATE *psf) ; 82 83/*-------------------------------------------------------------------------------------------- 84** Exported functions. 85*/ 86 87int 88float32_init (SF_PRIVATE *psf) 89{ static int float_caps ; 90 91 if (psf->sf.channels < 1) 92 { psf_log_printf (psf, "float32_init : internal error : channels = %d\n", psf->sf.channels) ; 93 return SFE_INTERNAL ; 94 } ; 95 96 float_caps = float32_get_capability (psf) ; 97 98 psf->blockwidth = sizeof (float) * psf->sf.channels ; 99 100 if (psf->file.mode == SFM_READ || psf->file.mode == SFM_RDWR) 101 { switch (psf->endian + float_caps) 102 { case (SF_ENDIAN_BIG + FLOAT_CAN_RW_BE) : 103 psf->data_endswap = SF_FALSE ; 104 psf->read_short = host_read_f2s ; 105 psf->read_int = host_read_f2i ; 106 psf->read_float = host_read_f ; 107 psf->read_double = host_read_f2d ; 108 break ; 109 110 case (SF_ENDIAN_LITTLE + FLOAT_CAN_RW_LE) : 111 psf->data_endswap = SF_FALSE ; 112 psf->read_short = host_read_f2s ; 113 psf->read_int = host_read_f2i ; 114 psf->read_float = host_read_f ; 115 psf->read_double = host_read_f2d ; 116 break ; 117 118 case (SF_ENDIAN_BIG + FLOAT_CAN_RW_LE) : 119 psf->data_endswap = SF_TRUE ; 120 psf->read_short = host_read_f2s ; 121 psf->read_int = host_read_f2i ; 122 psf->read_float = host_read_f ; 123 psf->read_double = host_read_f2d ; 124 break ; 125 126 case (SF_ENDIAN_LITTLE + FLOAT_CAN_RW_BE) : 127 psf->data_endswap = SF_TRUE ; 128 psf->read_short = host_read_f2s ; 129 psf->read_int = host_read_f2i ; 130 psf->read_float = host_read_f ; 131 psf->read_double = host_read_f2d ; 132 break ; 133 134 /* When the CPU is not IEEE compatible. */ 135 case (SF_ENDIAN_BIG + FLOAT_BROKEN_LE) : 136 psf->data_endswap = SF_TRUE ; 137 psf->read_short = replace_read_f2s ; 138 psf->read_int = replace_read_f2i ; 139 psf->read_float = replace_read_f ; 140 psf->read_double = replace_read_f2d ; 141 break ; 142 143 case (SF_ENDIAN_LITTLE + FLOAT_BROKEN_LE) : 144 psf->data_endswap = SF_FALSE ; 145 psf->read_short = replace_read_f2s ; 146 psf->read_int = replace_read_f2i ; 147 psf->read_float = replace_read_f ; 148 psf->read_double = replace_read_f2d ; 149 break ; 150 151 case (SF_ENDIAN_BIG + FLOAT_BROKEN_BE) : 152 psf->data_endswap = SF_FALSE ; 153 psf->read_short = replace_read_f2s ; 154 psf->read_int = replace_read_f2i ; 155 psf->read_float = replace_read_f ; 156 psf->read_double = replace_read_f2d ; 157 break ; 158 159 case (SF_ENDIAN_LITTLE + FLOAT_BROKEN_BE) : 160 psf->data_endswap = SF_TRUE ; 161 psf->read_short = replace_read_f2s ; 162 psf->read_int = replace_read_f2i ; 163 psf->read_float = replace_read_f ; 164 psf->read_double = replace_read_f2d ; 165 break ; 166 167 default : break ; 168 } ; 169 } ; 170 171 if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR) 172 { switch (psf->endian + float_caps) 173 { case (SF_ENDIAN_LITTLE + FLOAT_CAN_RW_LE) : 174 psf->data_endswap = SF_FALSE ; 175 psf->write_short = host_write_s2f ; 176 psf->write_int = host_write_i2f ; 177 psf->write_float = host_write_f ; 178 psf->write_double = host_write_d2f ; 179 break ; 180 181 case (SF_ENDIAN_BIG + FLOAT_CAN_RW_BE) : 182 psf->data_endswap = SF_FALSE ; 183 psf->write_short = host_write_s2f ; 184 psf->write_int = host_write_i2f ; 185 psf->write_float = host_write_f ; 186 psf->write_double = host_write_d2f ; 187 break ; 188 189 case (SF_ENDIAN_BIG + FLOAT_CAN_RW_LE) : 190 psf->data_endswap = SF_TRUE ; 191 psf->write_short = host_write_s2f ; 192 psf->write_int = host_write_i2f ; 193 psf->write_float = host_write_f ; 194 psf->write_double = host_write_d2f ; 195 break ; 196 197 case (SF_ENDIAN_LITTLE + FLOAT_CAN_RW_BE) : 198 psf->data_endswap = SF_TRUE ; 199 psf->write_short = host_write_s2f ; 200 psf->write_int = host_write_i2f ; 201 psf->write_float = host_write_f ; 202 psf->write_double = host_write_d2f ; 203 break ; 204 205 /* When the CPU is not IEEE compatible. */ 206 case (SF_ENDIAN_BIG + FLOAT_BROKEN_LE) : 207 psf->data_endswap = SF_TRUE ; 208 psf->write_short = replace_write_s2f ; 209 psf->write_int = replace_write_i2f ; 210 psf->write_float = replace_write_f ; 211 psf->write_double = replace_write_d2f ; 212 break ; 213 214 case (SF_ENDIAN_LITTLE + FLOAT_BROKEN_LE) : 215 psf->data_endswap = SF_FALSE ; 216 psf->write_short = replace_write_s2f ; 217 psf->write_int = replace_write_i2f ; 218 psf->write_float = replace_write_f ; 219 psf->write_double = replace_write_d2f ; 220 break ; 221 222 case (SF_ENDIAN_BIG + FLOAT_BROKEN_BE) : 223 psf->data_endswap = SF_FALSE ; 224 psf->write_short = replace_write_s2f ; 225 psf->write_int = replace_write_i2f ; 226 psf->write_float = replace_write_f ; 227 psf->write_double = replace_write_d2f ; 228 break ; 229 230 case (SF_ENDIAN_LITTLE + FLOAT_BROKEN_BE) : 231 psf->data_endswap = SF_TRUE ; 232 psf->write_short = replace_write_s2f ; 233 psf->write_int = replace_write_i2f ; 234 psf->write_float = replace_write_f ; 235 psf->write_double = replace_write_d2f ; 236 break ; 237 238 default : break ; 239 } ; 240 } ; 241 242 if (psf->filelength > psf->dataoffset) 243 { psf->datalength = (psf->dataend > 0) ? psf->dataend - psf->dataoffset : 244 psf->filelength - psf->dataoffset ; 245 } 246 else 247 psf->datalength = 0 ; 248 249 psf->sf.frames = psf->blockwidth > 0 ? psf->datalength / psf->blockwidth : 0 ; 250 251 return 0 ; 252} /* float32_init */ 253 254float 255float32_be_read (const unsigned char *cptr) 256{ int exponent, mantissa, negative ; 257 float fvalue ; 258 259 negative = cptr [0] & 0x80 ; 260 exponent = ((cptr [0] & 0x7F) << 1) | ((cptr [1] & 0x80) ? 1 : 0) ; 261 mantissa = ((cptr [1] & 0x7F) << 16) | (cptr [2] << 8) | (cptr [3]) ; 262 263 if (! (exponent || mantissa)) 264 return 0.0 ; 265 266 mantissa |= 0x800000 ; 267 exponent = exponent ? exponent - 127 : 0 ; 268 269 fvalue = mantissa ? ((float) mantissa) / ((float) 0x800000) : 0.0 ; 270 271 if (negative) 272 fvalue *= -1 ; 273 274 if (exponent > 0) 275 fvalue *= pow (2.0, exponent) ; 276 else if (exponent < 0) 277 fvalue /= pow (2.0, abs (exponent)) ; 278 279 return fvalue ; 280} /* float32_be_read */ 281 282float 283float32_le_read (const unsigned char *cptr) 284{ int exponent, mantissa, negative ; 285 float fvalue ; 286 287 negative = cptr [3] & 0x80 ; 288 exponent = ((cptr [3] & 0x7F) << 1) | ((cptr [2] & 0x80) ? 1 : 0) ; 289 mantissa = ((cptr [2] & 0x7F) << 16) | (cptr [1] << 8) | (cptr [0]) ; 290 291 if (! (exponent || mantissa)) 292 return 0.0 ; 293 294 mantissa |= 0x800000 ; 295 exponent = exponent ? exponent - 127 : 0 ; 296 297 fvalue = mantissa ? ((float) mantissa) / ((float) 0x800000) : 0.0 ; 298 299 if (negative) 300 fvalue *= -1 ; 301 302 if (exponent > 0) 303 fvalue *= pow (2.0, exponent) ; 304 else if (exponent < 0) 305 fvalue /= pow (2.0, abs (exponent)) ; 306 307 return fvalue ; 308} /* float32_le_read */ 309 310void 311float32_le_write (float in, unsigned char *out) 312{ int exponent, mantissa, negative = 0 ; 313 314 memset (out, 0, sizeof (int)) ; 315 316 if (fabs (in) < 1e-30) 317 return ; 318 319 if (in < 0.0) 320 { in *= -1.0 ; 321 negative = 1 ; 322 } ; 323 324 in = frexp (in, &exponent) ; 325 326 exponent += 126 ; 327 328 in *= (float) 0x1000000 ; 329 mantissa = (((int) in) & 0x7FFFFF) ; 330 331 if (negative) 332 out [3] |= 0x80 ; 333 334 if (exponent & 0x01) 335 out [2] |= 0x80 ; 336 337 out [0] = mantissa & 0xFF ; 338 out [1] = (mantissa >> 8) & 0xFF ; 339 out [2] |= (mantissa >> 16) & 0x7F ; 340 out [3] |= (exponent >> 1) & 0x7F ; 341 342 return ; 343} /* float32_le_write */ 344 345void 346float32_be_write (float in, unsigned char *out) 347{ int exponent, mantissa, negative = 0 ; 348 349 memset (out, 0, sizeof (int)) ; 350 351 if (fabs (in) < 1e-30) 352 return ; 353 354 if (in < 0.0) 355 { in *= -1.0 ; 356 negative = 1 ; 357 } ; 358 359 in = frexp (in, &exponent) ; 360 361 exponent += 126 ; 362 363 in *= (float) 0x1000000 ; 364 mantissa = (((int) in) & 0x7FFFFF) ; 365 366 if (negative) 367 out [0] |= 0x80 ; 368 369 if (exponent & 0x01) 370 out [1] |= 0x80 ; 371 372 out [3] = mantissa & 0xFF ; 373 out [2] = (mantissa >> 8) & 0xFF ; 374 out [1] |= (mantissa >> 16) & 0x7F ; 375 out [0] |= (exponent >> 1) & 0x7F ; 376 377 return ; 378} /* float32_be_write */ 379 380/*============================================================================================== 381** Private functions. 382*/ 383 384static void 385float32_peak_update (SF_PRIVATE *psf, const float *buffer, int count, sf_count_t indx) 386{ int chan ; 387 int k, position ; 388 float fmaxval ; 389 390 for (chan = 0 ; chan < psf->sf.channels ; chan++) 391 { fmaxval = fabs (buffer [chan]) ; 392 position = 0 ; 393 for (k = chan ; k < count ; k += psf->sf.channels) 394 if (fmaxval < fabs (buffer [k])) 395 { fmaxval = fabs (buffer [k]) ; 396 position = k ; 397 } ; 398 399 if (fmaxval > psf->peak_info->peaks [chan].value) 400 { psf->peak_info->peaks [chan].value = fmaxval ; 401 psf->peak_info->peaks [chan].position = psf->write_current + indx + (position / psf->sf.channels) ; 402 } ; 403 } ; 404 405 return ; 406} /* float32_peak_update */ 407 408static int 409float32_get_capability (SF_PRIVATE *psf) 410{ union 411 { float f ; 412 int i ; 413 unsigned char c [4] ; 414 } data ; 415 416 data.f = (float) 1.23456789 ; /* Some abitrary value. */ 417 418 if (! psf->ieee_replace) 419 { /* If this test is true ints and floats are compatible and little endian. */ 420 if (data.c [0] == 0x52 && data.c [1] == 0x06 && data.c [2] == 0x9e && data.c [3] == 0x3f) 421 return FLOAT_CAN_RW_LE ; 422 423 /* If this test is true ints and floats are compatible and big endian. */ 424 if (data.c [3] == 0x52 && data.c [2] == 0x06 && data.c [1] == 0x9e && data.c [0] == 0x3f) 425 return FLOAT_CAN_RW_BE ; 426 } ; 427 428 /* Floats are broken. Don't expect reading or writing to be fast. */ 429 psf_log_printf (psf, "Using IEEE replacement code for float.\n") ; 430 431 return (CPU_IS_LITTLE_ENDIAN) ? FLOAT_BROKEN_LE : FLOAT_BROKEN_BE ; 432} /* float32_get_capability */ 433 434/*======================================================================================= 435*/ 436 437static void 438f2s_array (const float *src, int count, short *dest, float scale) 439{ 440 for (int i = 0 ; i < count ; i++) 441 { dest [i] = psf_lrintf (scale * src [i]) ; 442 } ; 443} /* f2s_array */ 444 445static void 446f2s_clip_array (const float *src, int count, short *dest, float scale) 447{ for (int i = 0 ; i < count ; i++) 448 { float tmp = scale * src [i] ; 449 450 if (tmp > 32767.0) 451 dest [i] = SHRT_MAX ; 452 else if (tmp < -32768.0) 453 dest [i] = SHRT_MIN ; 454 else 455 dest [i] = psf_lrintf (tmp) ; 456 } ; 457} /* f2s_clip_array */ 458 459static inline void 460f2i_array (const float *src, int count, int *dest, float scale) 461{ for (int i = 0 ; i < count ; i++) 462 { dest [i] = psf_lrintf (scale * src [i]) ; 463 } ; 464} /* f2i_array */ 465 466static inline void 467f2i_clip_array (const float *src, int count, int *dest, float scale) 468{ for (int i = 0 ; i < count ; i++) 469 { float tmp = scale * src [i] ; 470 471 if (CPU_CLIPS_POSITIVE == 0 && tmp > (1.0 * INT_MAX)) 472 dest [i] = INT_MAX ; 473 else if (CPU_CLIPS_NEGATIVE == 0 && tmp < (-1.0 * INT_MAX)) 474 dest [i] = INT_MIN ; 475 else 476 dest [i] = psf_lrintf (tmp) ; 477 } ; 478} /* f2i_clip_array */ 479 480static inline void 481f2d_array (const float *src, int count, double *dest) 482{ for (int i = 0 ; i < count ; i++) 483 { dest [i] = src [i] ; 484 } ; 485} /* f2d_array */ 486 487static inline void 488s2f_array (const short *src, float *dest, int count, float scale) 489{ for (int i = 0 ; i < count ; i++) 490 { dest [i] = scale * src [i] ; 491 } ; 492} /* s2f_array */ 493 494static inline void 495i2f_array (const int *src, float *dest, int count, float scale) 496{ for (int i = 0 ; i < count ; i++) 497 { dest [i] = scale * src [i] ; 498 } ; 499} /* i2f_array */ 500 501static inline void 502d2f_array (const double *src, float *dest, int count) 503{ for (int i = 0 ; i < count ; i++) 504 { dest [i] = src [i] ; 505 } ; 506} /* d2f_array */ 507 508/*---------------------------------------------------------------------------------------------- 509*/ 510 511static sf_count_t 512host_read_f2s (SF_PRIVATE *psf, short *ptr, sf_count_t len) 513{ BUF_UNION ubuf ; 514 void (*convert) (const float *, int, short *, float) ; 515 int bufferlen, readcount ; 516 sf_count_t total = 0 ; 517 float scale ; 518 519 convert = (psf->add_clipping) ? f2s_clip_array : f2s_array ; 520 bufferlen = ARRAY_LEN (ubuf.fbuf) ; 521 scale = (psf->float_int_mult == 0) ? 1.0 : 0x7FFF / psf->float_max ; 522 523 while (len > 0) 524 { if (len < bufferlen) 525 bufferlen = (int) len ; 526 readcount = (int) psf_fread (ubuf.fbuf, sizeof (float), bufferlen, psf) ; 527 528/* Fix me : Need lef2s_array */ 529 if (psf->data_endswap == SF_TRUE) 530 endswap_int_array (ubuf.ibuf, readcount) ; 531 532 convert (ubuf.fbuf, readcount, ptr + total, scale) ; 533 total += readcount ; 534 if (readcount < bufferlen) 535 break ; 536 len -= readcount ; 537 } ; 538 539 return total ; 540} /* host_read_f2s */ 541 542static sf_count_t 543host_read_f2i (SF_PRIVATE *psf, int *ptr, sf_count_t len) 544{ BUF_UNION ubuf ; 545 void (*convert) (const float *, int, int *, float) ; 546 int bufferlen, readcount ; 547 sf_count_t total = 0 ; 548 float scale ; 549 550 convert = (psf->add_clipping) ? f2i_clip_array : f2i_array ; 551 bufferlen = ARRAY_LEN (ubuf.fbuf) ; 552 scale = (psf->float_int_mult == 0) ? 1.0 : 2147483648.0f / psf->float_max ; 553 554 while (len > 0) 555 { if (len < bufferlen) 556 bufferlen = (int) len ; 557 readcount = (int) psf_fread (ubuf.fbuf, sizeof (float), bufferlen, psf) ; 558 559 if (psf->data_endswap == SF_TRUE) 560 endswap_int_array (ubuf.ibuf, bufferlen) ; 561 562 convert (ubuf.fbuf, readcount, ptr + total, scale) ; 563 total += readcount ; 564 if (readcount < bufferlen) 565 break ; 566 len -= readcount ; 567 } ; 568 569 return total ; 570} /* host_read_f2i */ 571 572static sf_count_t 573host_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) 574{ BUF_UNION ubuf ; 575 int bufferlen, readcount ; 576 sf_count_t total = 0 ; 577 578 if (psf->data_endswap != SF_TRUE) 579 return psf_fread (ptr, sizeof (float), len, psf) ; 580 581 bufferlen = ARRAY_LEN (ubuf.fbuf) ; 582 583 while (len > 0) 584 { if (len < bufferlen) 585 bufferlen = (int) len ; 586 readcount = (int) psf_fread (ubuf.fbuf, sizeof (float), bufferlen, psf) ; 587 588 endswap_int_copy ((int*) (ptr + total), ubuf.ibuf, readcount) ; 589 590 total += readcount ; 591 if (readcount < bufferlen) 592 break ; 593 len -= readcount ; 594 } ; 595 596 return total ; 597} /* host_read_f */ 598 599static sf_count_t 600host_read_f2d (SF_PRIVATE *psf, double *ptr, sf_count_t len) 601{ BUF_UNION ubuf ; 602 int bufferlen, readcount ; 603 sf_count_t total = 0 ; 604 605 bufferlen = ARRAY_LEN (ubuf.fbuf) ; 606 607 while (len > 0) 608 { if (len < bufferlen) 609 bufferlen = (int) len ; 610 readcount = (int) psf_fread (ubuf.fbuf, sizeof (float), bufferlen, psf) ; 611 612 if (psf->data_endswap == SF_TRUE) 613 endswap_int_array (ubuf.ibuf, bufferlen) ; 614 615/* Fix me : Need lef2d_array */ 616 f2d_array (ubuf.fbuf, readcount, ptr + total) ; 617 total += readcount ; 618 if (readcount < bufferlen) 619 break ; 620 len -= readcount ; 621 } ; 622 623 return total ; 624} /* host_read_f2d */ 625 626static sf_count_t 627host_write_s2f (SF_PRIVATE *psf, const short *ptr, sf_count_t len) 628{ BUF_UNION ubuf ; 629 int bufferlen, writecount ; 630 sf_count_t total = 0 ; 631 float scale ; 632 633/* Erik */ 634 scale = (psf->scale_int_float == 0) ? 1.0 : 1.0 / 0x8000 ; 635 bufferlen = ARRAY_LEN (ubuf.fbuf) ; 636 637 while (len > 0) 638 { if (len < bufferlen) 639 bufferlen = (int) len ; 640 s2f_array (ptr + total, ubuf.fbuf, bufferlen, scale) ; 641 642 if (psf->peak_info) 643 float32_peak_update (psf, ubuf.fbuf, bufferlen, total / psf->sf.channels) ; 644 645 if (psf->data_endswap == SF_TRUE) 646 endswap_int_array (ubuf.ibuf, bufferlen) ; 647 648 writecount = (int) psf_fwrite (ubuf.fbuf, sizeof (float), bufferlen, psf) ; 649 total += writecount ; 650 if (writecount < bufferlen) 651 break ; 652 len -= writecount ; 653 } ; 654 655 return total ; 656} /* host_write_s2f */ 657 658static sf_count_t 659host_write_i2f (SF_PRIVATE *psf, const int *ptr, sf_count_t len) 660{ BUF_UNION ubuf ; 661 int bufferlen, writecount ; 662 sf_count_t total = 0 ; 663 float scale ; 664 665 scale = (psf->scale_int_float == 0) ? 1.0 : 1.0 / (8.0 * 0x10000000) ; 666 bufferlen = ARRAY_LEN (ubuf.fbuf) ; 667 668 while (len > 0) 669 { if (len < bufferlen) 670 bufferlen = (int) len ; 671 i2f_array (ptr + total, ubuf.fbuf, bufferlen, scale) ; 672 673 if (psf->peak_info) 674 float32_peak_update (psf, ubuf.fbuf, bufferlen, total / psf->sf.channels) ; 675 676 if (psf->data_endswap == SF_TRUE) 677 endswap_int_array (ubuf.ibuf, bufferlen) ; 678 679 writecount = (int) psf_fwrite (ubuf.fbuf, sizeof (float) , bufferlen, psf) ; 680 total += writecount ; 681 if (writecount < bufferlen) 682 break ; 683 len -= writecount ; 684 } ; 685 686 return total ; 687} /* host_write_i2f */ 688 689static sf_count_t 690host_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) 691{ BUF_UNION ubuf ; 692 int bufferlen, writecount ; 693 sf_count_t total = 0 ; 694 695 if (psf->peak_info) 696 float32_peak_update (psf, ptr, len, 0) ; 697 698 if (psf->data_endswap != SF_TRUE) 699 return psf_fwrite (ptr, sizeof (float), len, psf) ; 700 701 bufferlen = ARRAY_LEN (ubuf.fbuf) ; 702 703 while (len > 0) 704 { if (len < bufferlen) 705 bufferlen = (int) len ; 706 707 endswap_int_copy (ubuf.ibuf, (const int*) (ptr + total), bufferlen) ; 708 709 writecount = (int) psf_fwrite (ubuf.fbuf, sizeof (float), bufferlen, psf) ; 710 total += writecount ; 711 if (writecount < bufferlen) 712 break ; 713 len -= writecount ; 714 } ; 715 716 return total ; 717} /* host_write_f */ 718 719static sf_count_t 720host_write_d2f (SF_PRIVATE *psf, const double *ptr, sf_count_t len) 721{ BUF_UNION ubuf ; 722 int bufferlen, writecount ; 723 sf_count_t total = 0 ; 724 725 bufferlen = ARRAY_LEN (ubuf.fbuf) ; 726 727 while (len > 0) 728 { if (len < bufferlen) 729 bufferlen = (int) len ; 730 731 d2f_array (ptr + total, ubuf.fbuf, bufferlen) ; 732 733 if (psf->peak_info) 734 float32_peak_update (psf, ubuf.fbuf, bufferlen, total / psf->sf.channels) ; 735 736 if (psf->data_endswap == SF_TRUE) 737 endswap_int_array (ubuf.ibuf, bufferlen) ; 738 739 writecount = (int) psf_fwrite (ubuf.fbuf, sizeof (float), bufferlen, psf) ; 740 total += writecount ; 741 if (writecount < bufferlen) 742 break ; 743 len -= writecount ; 744 } ; 745 746 return total ; 747} /* host_write_d2f */ 748 749/*======================================================================================= 750*/ 751 752static sf_count_t 753replace_read_f2s (SF_PRIVATE *psf, short *ptr, sf_count_t len) 754{ BUF_UNION ubuf ; 755 int bufferlen, readcount ; 756 sf_count_t total = 0 ; 757 float scale ; 758 759 bufferlen = ARRAY_LEN (ubuf.fbuf) ; 760 scale = (psf->float_int_mult == 0) ? 1.0 : 0x7FFF / psf->float_max ; 761 762 while (len > 0) 763 { if (len < bufferlen) 764 bufferlen = (int) len ; 765 readcount = (int) psf_fread (ubuf.fbuf, sizeof (float), bufferlen, psf) ; 766 767 if (psf->data_endswap == SF_TRUE) 768 endswap_int_array (ubuf.ibuf, bufferlen) ; 769 770 bf2f_array (ubuf.fbuf, bufferlen) ; 771 772 f2s_array (ubuf.fbuf, readcount, ptr + total, scale) ; 773 total += readcount ; 774 if (readcount < bufferlen) 775 break ; 776 len -= readcount ; 777 } ; 778 779 return total ; 780} /* replace_read_f2s */ 781 782static sf_count_t 783replace_read_f2i (SF_PRIVATE *psf, int *ptr, sf_count_t len) 784{ BUF_UNION ubuf ; 785 int bufferlen, readcount ; 786 sf_count_t total = 0 ; 787 float scale ; 788 789 bufferlen = ARRAY_LEN (ubuf.fbuf) ; 790 scale = (psf->float_int_mult == 0) ? 1.0 : 2147483648.0f / psf->float_max ; 791 792 while (len > 0) 793 { if (len < bufferlen) 794 bufferlen = (int) len ; 795 readcount = (int) psf_fread (ubuf.fbuf, sizeof (float), bufferlen, psf) ; 796 797 if (psf->data_endswap == SF_TRUE) 798 endswap_int_array (ubuf.ibuf, bufferlen) ; 799 800 bf2f_array (ubuf.fbuf, bufferlen) ; 801 802 f2i_array (ubuf.fbuf, readcount, ptr + total, scale) ; 803 total += readcount ; 804 if (readcount < bufferlen) 805 break ; 806 len -= readcount ; 807 } ; 808 809 return total ; 810} /* replace_read_f2i */ 811 812static sf_count_t 813replace_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) 814{ BUF_UNION ubuf ; 815 int bufferlen, readcount ; 816 sf_count_t total = 0 ; 817 818 /* FIX THIS */ 819 820 bufferlen = ARRAY_LEN (ubuf.fbuf) ; 821 822 while (len > 0) 823 { if (len < bufferlen) 824 bufferlen = (int) len ; 825 readcount = (int) psf_fread (ubuf.fbuf, sizeof (float), bufferlen, psf) ; 826 827 if (psf->data_endswap == SF_TRUE) 828 endswap_int_array (ubuf.ibuf, bufferlen) ; 829 830 bf2f_array (ubuf.fbuf, bufferlen) ; 831 832 memcpy (ptr + total, ubuf.fbuf, bufferlen * sizeof (float)) ; 833 834 total += readcount ; 835 if (readcount < bufferlen) 836 break ; 837 len -= readcount ; 838 } ; 839 840 return total ; 841} /* replace_read_f */ 842 843static sf_count_t 844replace_read_f2d (SF_PRIVATE *psf, double *ptr, sf_count_t len) 845{ BUF_UNION ubuf ; 846 int bufferlen, readcount ; 847 sf_count_t total = 0 ; 848 849 bufferlen = ARRAY_LEN (ubuf.fbuf) ; 850 851 while (len > 0) 852 { if (len < bufferlen) 853 bufferlen = (int) len ; 854 readcount = (int) psf_fread (ubuf.fbuf, sizeof (float), bufferlen, psf) ; 855 856 if (psf->data_endswap == SF_TRUE) 857 endswap_int_array (ubuf.ibuf, bufferlen) ; 858 859 bf2f_array (ubuf.fbuf, bufferlen) ; 860 861 f2d_array (ubuf.fbuf, readcount, ptr + total) ; 862 total += readcount ; 863 if (readcount < bufferlen) 864 break ; 865 len -= readcount ; 866 } ; 867 868 return total ; 869} /* replace_read_f2d */ 870 871static sf_count_t 872replace_write_s2f (SF_PRIVATE *psf, const short *ptr, sf_count_t len) 873{ BUF_UNION ubuf ; 874 int bufferlen, writecount ; 875 sf_count_t total = 0 ; 876 float scale ; 877 878 scale = (psf->scale_int_float == 0) ? 1.0 : 1.0 / 0x8000 ; 879 bufferlen = ARRAY_LEN (ubuf.fbuf) ; 880 881 while (len > 0) 882 { if (len < bufferlen) 883 bufferlen = (int) len ; 884 s2f_array (ptr + total, ubuf.fbuf, bufferlen, scale) ; 885 886 if (psf->peak_info) 887 float32_peak_update (psf, ubuf.fbuf, bufferlen, total / psf->sf.channels) ; 888 889 f2bf_array (ubuf.fbuf, bufferlen) ; 890 891 if (psf->data_endswap == SF_TRUE) 892 endswap_int_array (ubuf.ibuf, bufferlen) ; 893 894 writecount = (int) psf_fwrite (ubuf.fbuf, sizeof (float), bufferlen, psf) ; 895 total += writecount ; 896 if (writecount < bufferlen) 897 break ; 898 len -= writecount ; 899 } ; 900 901 return total ; 902} /* replace_write_s2f */ 903 904static sf_count_t 905replace_write_i2f (SF_PRIVATE *psf, const int *ptr, sf_count_t len) 906{ BUF_UNION ubuf ; 907 int bufferlen, writecount ; 908 sf_count_t total = 0 ; 909 float scale ; 910 911 scale = (psf->scale_int_float == 0) ? 1.0 : 1.0 / (8.0 * 0x10000000) ; 912 bufferlen = ARRAY_LEN (ubuf.fbuf) ; 913 914 while (len > 0) 915 { if (len < bufferlen) 916 bufferlen = (int) len ; 917 i2f_array (ptr + total, ubuf.fbuf, bufferlen, scale) ; 918 919 if (psf->peak_info) 920 float32_peak_update (psf, ubuf.fbuf, bufferlen, total / psf->sf.channels) ; 921 922 f2bf_array (ubuf.fbuf, bufferlen) ; 923 924 if (psf->data_endswap == SF_TRUE) 925 endswap_int_array (ubuf.ibuf, bufferlen) ; 926 927 writecount = (int) psf_fwrite (ubuf.fbuf, sizeof (float), bufferlen, psf) ; 928 total += writecount ; 929 if (writecount < bufferlen) 930 break ; 931 len -= writecount ; 932 } ; 933 934 return total ; 935} /* replace_write_i2f */ 936 937static sf_count_t 938replace_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) 939{ BUF_UNION ubuf ; 940 int bufferlen, writecount ; 941 sf_count_t total = 0 ; 942 943 /* FIX THIS */ 944 if (psf->peak_info) 945 float32_peak_update (psf, ptr, len, 0) ; 946 947 bufferlen = ARRAY_LEN (ubuf.fbuf) ; 948 949 while (len > 0) 950 { if (len < bufferlen) 951 bufferlen = (int) len ; 952 953 memcpy (ubuf.fbuf, ptr + total, bufferlen * sizeof (float)) ; 954 955 f2bf_array (ubuf.fbuf, bufferlen) ; 956 957 if (psf->data_endswap == SF_TRUE) 958 endswap_int_array (ubuf.ibuf, bufferlen) ; 959 960 writecount = (int) psf_fwrite (ubuf.fbuf, sizeof (float) , bufferlen, psf) ; 961 total += writecount ; 962 if (writecount < bufferlen) 963 break ; 964 len -= writecount ; 965 } ; 966 967 return total ; 968} /* replace_write_f */ 969 970static sf_count_t 971replace_write_d2f (SF_PRIVATE *psf, const double *ptr, sf_count_t len) 972{ BUF_UNION ubuf ; 973 int bufferlen, writecount ; 974 sf_count_t total = 0 ; 975 976 bufferlen = ARRAY_LEN (ubuf.fbuf) ; 977 978 while (len > 0) 979 { if (len < bufferlen) 980 bufferlen = (int) len ; 981 d2f_array (ptr + total, ubuf.fbuf, bufferlen) ; 982 983 if (psf->peak_info) 984 float32_peak_update (psf, ubuf.fbuf, bufferlen, total / psf->sf.channels) ; 985 986 f2bf_array (ubuf.fbuf, bufferlen) ; 987 988 if (psf->data_endswap == SF_TRUE) 989 endswap_int_array (ubuf.ibuf, bufferlen) ; 990 991 writecount = (int) psf_fwrite (ubuf.fbuf, sizeof (float), bufferlen, psf) ; 992 total += writecount ; 993 if (writecount < bufferlen) 994 break ; 995 len -= writecount ; 996 } ; 997 998 return total ; 999} /* replace_write_d2f */ 1000 1001/*---------------------------------------------------------------------------------------------- 1002*/ 1003 1004static void 1005bf2f_array (float *buffer, int count) 1006{ for (int i = 0 ; i < count ; i++) 1007 { buffer [i] = FLOAT32_READ ((unsigned char *) &buffer [i]) ; 1008 } ; 1009} /* bf2f_array */ 1010 1011static void 1012f2bf_array (float *buffer, int count) 1013{ for (int i = 0 ; i < count ; i++) 1014 { FLOAT32_WRITE (buffer [i], (unsigned char*) &buffer [i]) ; 1015 } ; 1016} /* f2bf_array */ 1017 1018