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 <fcntl.h> 24#include <string.h> 25#include <ctype.h> 26#include <math.h> 27 28#include "sndfile.h" 29#include "sfendian.h" 30#include "common.h" 31 32/*------------------------------------------------------------------------------ 33** Macros to handle big/little endian issues. 34*/ 35 36#define FAP_MARKER (MAKE_MARKER ('f', 'a', 'p', ' ')) 37#define PAF_MARKER (MAKE_MARKER (' ', 'p', 'a', 'f')) 38 39/*------------------------------------------------------------------------------ 40** Other defines. 41*/ 42 43#define PAF_HEADER_LENGTH 2048 44 45#define PAF24_SAMPLES_PER_BLOCK 10 46#define PAF24_BLOCK_SIZE 32 47 48/*------------------------------------------------------------------------------ 49** Typedefs. 50*/ 51 52typedef struct 53{ int version ; 54 int endianness ; 55 int samplerate ; 56 int format ; 57 int channels ; 58 int source ; 59} PAF_FMT ; 60 61typedef struct 62{ int max_blocks, channels, blocksize ; 63 int read_block, write_block, read_count, write_count ; 64 sf_count_t sample_count ; 65 int *samples ; 66 int *block ; 67 int data [] ; /* ISO C99 struct flexible array. */ 68} PAF24_PRIVATE ; 69 70/*------------------------------------------------------------------------------ 71** Private static functions. 72*/ 73 74static int paf24_init (SF_PRIVATE *psf) ; 75 76static int paf_read_header (SF_PRIVATE *psf) ; 77static int paf_write_header (SF_PRIVATE *psf, int calc_length) ; 78 79static sf_count_t paf24_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ; 80static sf_count_t paf24_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ; 81static sf_count_t paf24_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ; 82static sf_count_t paf24_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ; 83 84static sf_count_t paf24_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ; 85static sf_count_t paf24_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ; 86static sf_count_t paf24_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ; 87static sf_count_t paf24_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ; 88 89static sf_count_t paf24_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ; 90 91enum 92{ PAF_PCM_16 = 0, 93 PAF_PCM_24 = 1, 94 PAF_PCM_S8 = 2 95} ; 96 97/*------------------------------------------------------------------------------ 98** Public function. 99*/ 100 101int 102paf_open (SF_PRIVATE *psf) 103{ int subformat, error, endian ; 104 105 psf->dataoffset = PAF_HEADER_LENGTH ; 106 107 if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0)) 108 { if ((error = paf_read_header (psf))) 109 return error ; 110 } ; 111 112 subformat = SF_CODEC (psf->sf.format) ; 113 114 if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR) 115 { if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_PAF) 116 return SFE_BAD_OPEN_FORMAT ; 117 118 endian = SF_ENDIAN (psf->sf.format) ; 119 120 /* PAF is by default big endian. */ 121 psf->endian = SF_ENDIAN_BIG ; 122 123 if (endian == SF_ENDIAN_LITTLE || (CPU_IS_LITTLE_ENDIAN && (endian == SF_ENDIAN_CPU))) 124 psf->endian = SF_ENDIAN_LITTLE ; 125 126 if ((error = paf_write_header (psf, SF_FALSE))) 127 return error ; 128 129 psf->write_header = paf_write_header ; 130 } ; 131 132 switch (subformat) 133 { case SF_FORMAT_PCM_S8 : 134 psf->bytewidth = 1 ; 135 error = pcm_init (psf) ; 136 break ; 137 138 case SF_FORMAT_PCM_16 : 139 psf->bytewidth = 2 ; 140 error = pcm_init (psf) ; 141 break ; 142 143 case SF_FORMAT_PCM_24 : 144 /* No bytewidth because of whacky 24 bit encoding. */ 145 error = paf24_init (psf) ; 146 break ; 147 148 default : return SFE_PAF_UNKNOWN_FORMAT ; 149 } ; 150 151 return error ; 152} /* paf_open */ 153 154/*------------------------------------------------------------------------------ 155*/ 156 157static int 158paf_read_header (SF_PRIVATE *psf) 159{ PAF_FMT paf_fmt ; 160 int marker ; 161 162 if (psf->filelength < PAF_HEADER_LENGTH) 163 return SFE_PAF_SHORT_HEADER ; 164 165 memset (&paf_fmt, 0, sizeof (paf_fmt)) ; 166 psf_binheader_readf (psf, "pm", 0, &marker) ; 167 168 psf_log_printf (psf, "Signature : '%M'\n", marker) ; 169 170 if (marker == PAF_MARKER) 171 { psf_binheader_readf (psf, "E444444", &(paf_fmt.version), &(paf_fmt.endianness), 172 &(paf_fmt.samplerate), &(paf_fmt.format), &(paf_fmt.channels), &(paf_fmt.source)) ; 173 } 174 else if (marker == FAP_MARKER) 175 { psf_binheader_readf (psf, "e444444", &(paf_fmt.version), &(paf_fmt.endianness), 176 &(paf_fmt.samplerate), &(paf_fmt.format), &(paf_fmt.channels), &(paf_fmt.source)) ; 177 } 178 else 179 return SFE_PAF_NO_MARKER ; 180 181 psf_log_printf (psf, "Version : %d\n", paf_fmt.version) ; 182 183 if (paf_fmt.version != 0) 184 { psf_log_printf (psf, "*** Bad version number. should be zero.\n") ; 185 return SFE_PAF_VERSION ; 186 } ; 187 188 psf_log_printf (psf, "Sample Rate : %d\n", paf_fmt.samplerate) ; 189 psf_log_printf (psf, "Channels : %d\n", paf_fmt.channels) ; 190 191 psf_log_printf (psf, "Endianness : %d => ", paf_fmt.endianness) ; 192 if (paf_fmt.endianness) 193 { psf_log_printf (psf, "Little\n", paf_fmt.endianness) ; 194 psf->endian = SF_ENDIAN_LITTLE ; 195 } 196 else 197 { psf_log_printf (psf, "Big\n", paf_fmt.endianness) ; 198 psf->endian = SF_ENDIAN_BIG ; 199 } ; 200 201 if (paf_fmt.channels < 1 || paf_fmt.channels > SF_MAX_CHANNELS) 202 return SFE_PAF_BAD_CHANNELS ; 203 204 psf->datalength = psf->filelength - psf->dataoffset ; 205 206 psf_binheader_readf (psf, "p", (int) psf->dataoffset) ; 207 208 psf->sf.samplerate = paf_fmt.samplerate ; 209 psf->sf.channels = paf_fmt.channels ; 210 211 /* Only fill in type major. */ 212 psf->sf.format = SF_FORMAT_PAF ; 213 214 psf_log_printf (psf, "Format : %d => ", paf_fmt.format) ; 215 216 /* PAF is by default big endian. */ 217 psf->sf.format |= paf_fmt.endianness ? SF_ENDIAN_LITTLE : SF_ENDIAN_BIG ; 218 219 switch (paf_fmt.format) 220 { case PAF_PCM_S8 : 221 psf_log_printf (psf, "8 bit linear PCM\n") ; 222 psf->bytewidth = 1 ; 223 224 psf->sf.format |= SF_FORMAT_PCM_S8 ; 225 226 psf->blockwidth = psf->bytewidth * psf->sf.channels ; 227 psf->sf.frames = psf->datalength / psf->blockwidth ; 228 break ; 229 230 case PAF_PCM_16 : 231 psf_log_printf (psf, "16 bit linear PCM\n") ; 232 psf->bytewidth = 2 ; 233 234 psf->sf.format |= SF_FORMAT_PCM_16 ; 235 236 psf->blockwidth = psf->bytewidth * psf->sf.channels ; 237 psf->sf.frames = psf->datalength / psf->blockwidth ; 238 break ; 239 240 case PAF_PCM_24 : 241 psf_log_printf (psf, "24 bit linear PCM\n") ; 242 psf->bytewidth = 3 ; 243 244 psf->sf.format |= SF_FORMAT_PCM_24 ; 245 246 psf->blockwidth = 0 ; 247 psf->sf.frames = PAF24_SAMPLES_PER_BLOCK * psf->datalength / 248 (PAF24_BLOCK_SIZE * psf->sf.channels) ; 249 break ; 250 251 default : psf_log_printf (psf, "Unknown\n") ; 252 return SFE_PAF_UNKNOWN_FORMAT ; 253 break ; 254 } ; 255 256 psf_log_printf (psf, "Source : %d => ", paf_fmt.source) ; 257 258 switch (paf_fmt.source) 259 { case 1 : psf_log_printf (psf, "Analog Recording\n") ; 260 break ; 261 case 2 : psf_log_printf (psf, "Digital Transfer\n") ; 262 break ; 263 case 3 : psf_log_printf (psf, "Multi-track Mixdown\n") ; 264 break ; 265 case 5 : psf_log_printf (psf, "Audio Resulting From DSP Processing\n") ; 266 break ; 267 default : psf_log_printf (psf, "Unknown\n") ; 268 break ; 269 } ; 270 271 return 0 ; 272} /* paf_read_header */ 273 274static int 275paf_write_header (SF_PRIVATE *psf, int UNUSED (calc_length)) 276{ int paf_format ; 277 278 /* PAF header already written so no need to re-write. */ 279 if (psf_ftell (psf) >= PAF_HEADER_LENGTH) 280 return 0 ; 281 282 psf->dataoffset = PAF_HEADER_LENGTH ; 283 284 switch (SF_CODEC (psf->sf.format)) 285 { case SF_FORMAT_PCM_S8 : 286 paf_format = PAF_PCM_S8 ; 287 break ; 288 289 case SF_FORMAT_PCM_16 : 290 paf_format = PAF_PCM_16 ; 291 break ; 292 293 case SF_FORMAT_PCM_24 : 294 paf_format = PAF_PCM_24 ; 295 break ; 296 297 default : return SFE_PAF_UNKNOWN_FORMAT ; 298 } ; 299 300 /* Reset the current header length to zero. */ 301 psf->header.ptr [0] = 0 ; 302 psf->header.indx = 0 ; 303 304 if (psf->endian == SF_ENDIAN_BIG) 305 { /* Marker, version, endianness, samplerate */ 306 psf_binheader_writef (psf, "Em444", BHWm (PAF_MARKER), BHW4 (0), BHW4 (0), BHW4 (psf->sf.samplerate)) ; 307 /* format, channels, source */ 308 psf_binheader_writef (psf, "E444", BHW4 (paf_format), BHW4 (psf->sf.channels), BHW4 (0)) ; 309 } 310 else if (psf->endian == SF_ENDIAN_LITTLE) 311 { /* Marker, version, endianness, samplerate */ 312 psf_binheader_writef (psf, "em444", BHWm (FAP_MARKER), BHW4 (0), BHW4 (1), BHW4 (psf->sf.samplerate)) ; 313 /* format, channels, source */ 314 psf_binheader_writef (psf, "e444", BHW4 (paf_format), BHW4 (psf->sf.channels), BHW4 (0)) ; 315 } ; 316 317 /* Zero fill to dataoffset. */ 318 psf_binheader_writef (psf, "z", BHWz ((size_t) (psf->dataoffset - psf->header.indx))) ; 319 320 psf_fwrite (psf->header.ptr, psf->header.indx, 1, psf) ; 321 322 return psf->error ; 323} /* paf_write_header */ 324 325/*=============================================================================== 326** 24 bit PAF files have a really weird encoding. 327** For a mono file, 10 samples (each being 3 bytes) are packed into a 32 byte 328** block. The 8 ints in this 32 byte block are then endian swapped (as ints) 329** if necessary before being written to disk. 330** For a stereo file, blocks of 10 samples from the same channel are encoded 331** into 32 bytes as for the mono case. The 32 byte blocks are then interleaved 332** on disk. 333** Reading has to reverse the above process :-). 334** Weird!!! 335** 336** The code below attempts to gain efficiency while maintaining readability. 337*/ 338 339static int paf24_read_block (SF_PRIVATE *psf, PAF24_PRIVATE *ppaf24) ; 340static int paf24_write_block (SF_PRIVATE *psf, PAF24_PRIVATE *ppaf24) ; 341static int paf24_close (SF_PRIVATE *psf) ; 342 343 344static int 345paf24_init (SF_PRIVATE *psf) 346{ PAF24_PRIVATE *ppaf24 ; 347 int paf24size ; 348 349 paf24size = sizeof (PAF24_PRIVATE) + psf->sf.channels * 350 (PAF24_BLOCK_SIZE + PAF24_SAMPLES_PER_BLOCK * sizeof (int)) ; 351 352 /* 353 ** Not exatly sure why this needs to be here but the tests 354 ** fail without it. 355 */ 356 psf->last_op = 0 ; 357 358 if (! (psf->codec_data = calloc (1, paf24size))) 359 return SFE_MALLOC_FAILED ; 360 361 ppaf24 = (PAF24_PRIVATE*) psf->codec_data ; 362 363 ppaf24->channels = psf->sf.channels ; 364 ppaf24->samples = ppaf24->data ; 365 ppaf24->block = ppaf24->data + PAF24_SAMPLES_PER_BLOCK * ppaf24->channels ; 366 367 ppaf24->blocksize = PAF24_BLOCK_SIZE * ppaf24->channels ; 368 369 if (psf->file.mode == SFM_READ || psf->file.mode == SFM_RDWR) 370 { paf24_read_block (psf, ppaf24) ; /* Read first block. */ 371 372 psf->read_short = paf24_read_s ; 373 psf->read_int = paf24_read_i ; 374 psf->read_float = paf24_read_f ; 375 psf->read_double = paf24_read_d ; 376 } ; 377 378 if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR) 379 { psf->write_short = paf24_write_s ; 380 psf->write_int = paf24_write_i ; 381 psf->write_float = paf24_write_f ; 382 psf->write_double = paf24_write_d ; 383 } ; 384 385 psf->seek = paf24_seek ; 386 psf->container_close = paf24_close ; 387 388 psf->filelength = psf_get_filelen (psf) ; 389 psf->datalength = psf->filelength - psf->dataoffset ; 390 391 if (psf->datalength % PAF24_BLOCK_SIZE) 392 { if (psf->file.mode == SFM_READ) 393 psf_log_printf (psf, "*** Warning : file seems to be truncated.\n") ; 394 ppaf24->max_blocks = psf->datalength / ppaf24->blocksize + 1 ; 395 } 396 else 397 ppaf24->max_blocks = psf->datalength / ppaf24->blocksize ; 398 399 ppaf24->read_block = 0 ; 400 if (psf->file.mode == SFM_RDWR) 401 ppaf24->write_block = ppaf24->max_blocks ; 402 else 403 ppaf24->write_block = 0 ; 404 405 psf->sf.frames = PAF24_SAMPLES_PER_BLOCK * ppaf24->max_blocks ; 406 ppaf24->sample_count = psf->sf.frames ; 407 408 return 0 ; 409} /* paf24_init */ 410 411static sf_count_t 412paf24_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) 413{ PAF24_PRIVATE *ppaf24 ; 414 int newblock, newsample ; 415 416 if (psf->codec_data == NULL) 417 { psf->error = SFE_INTERNAL ; 418 return PSF_SEEK_ERROR ; 419 } ; 420 421 ppaf24 = (PAF24_PRIVATE*) psf->codec_data ; 422 423 if (mode == SFM_READ && ppaf24->write_count > 0) 424 paf24_write_block (psf, ppaf24) ; 425 426 newblock = offset / PAF24_SAMPLES_PER_BLOCK ; 427 newsample = offset % PAF24_SAMPLES_PER_BLOCK ; 428 429 switch (mode) 430 { case SFM_READ : 431 if (psf->last_op == SFM_WRITE && ppaf24->write_count) 432 paf24_write_block (psf, ppaf24) ; 433 434 psf_fseek (psf, psf->dataoffset + newblock * ppaf24->blocksize, SEEK_SET) ; 435 ppaf24->read_block = newblock ; 436 paf24_read_block (psf, ppaf24) ; 437 ppaf24->read_count = newsample ; 438 break ; 439 440 case SFM_WRITE : 441 if (offset > ppaf24->sample_count) 442 { psf->error = SFE_BAD_SEEK ; 443 return PSF_SEEK_ERROR ; 444 } ; 445 446 if (psf->last_op == SFM_WRITE && ppaf24->write_count) 447 paf24_write_block (psf, ppaf24) ; 448 449 psf_fseek (psf, psf->dataoffset + newblock * ppaf24->blocksize, SEEK_SET) ; 450 ppaf24->write_block = newblock ; 451 paf24_read_block (psf, ppaf24) ; 452 ppaf24->write_count = newsample ; 453 break ; 454 455 default : 456 psf->error = SFE_BAD_SEEK ; 457 return PSF_SEEK_ERROR ; 458 } ; 459 460 return newblock * PAF24_SAMPLES_PER_BLOCK + newsample ; 461} /* paf24_seek */ 462 463static int 464paf24_close (SF_PRIVATE *psf) 465{ PAF24_PRIVATE *ppaf24 ; 466 467 if (psf->codec_data == NULL) 468 return 0 ; 469 470 ppaf24 = (PAF24_PRIVATE*) psf->codec_data ; 471 472 if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR) 473 { if (ppaf24->write_count > 0) 474 paf24_write_block (psf, ppaf24) ; 475 } ; 476 477 return 0 ; 478} /* paf24_close */ 479 480/*--------------------------------------------------------------------------- 481*/ 482static int 483paf24_read_block (SF_PRIVATE *psf, PAF24_PRIVATE *ppaf24) 484{ int k, channel ; 485 unsigned char *cptr ; 486 487 ppaf24->read_block ++ ; 488 ppaf24->read_count = 0 ; 489 490 if (ppaf24->read_block * PAF24_SAMPLES_PER_BLOCK > ppaf24->sample_count) 491 { memset (ppaf24->samples, 0, PAF24_SAMPLES_PER_BLOCK * ppaf24->channels) ; 492 return 1 ; 493 } ; 494 495 /* Read the block. */ 496 if ((k = (int) psf_fread (ppaf24->block, 1, ppaf24->blocksize, psf)) != ppaf24->blocksize) 497 psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, ppaf24->blocksize) ; 498 499 /* Do endian swapping if necessary. */ 500 if ((CPU_IS_BIG_ENDIAN && psf->endian == SF_ENDIAN_LITTLE) || (CPU_IS_LITTLE_ENDIAN && psf->endian == SF_ENDIAN_BIG)) 501 endswap_int_array (ppaf24->block, 8 * ppaf24->channels) ; 502 503 /* Unpack block. */ 504 for (k = 0 ; k < PAF24_SAMPLES_PER_BLOCK * ppaf24->channels ; k++) 505 { channel = k % ppaf24->channels ; 506 cptr = ((unsigned char *) ppaf24->block) + PAF24_BLOCK_SIZE * channel + 3 * (k / ppaf24->channels) ; 507 ppaf24->samples [k] = (cptr [0] << 8) | (cptr [1] << 16) | (((unsigned) cptr [2]) << 24) ; 508 } ; 509 510 return 1 ; 511} /* paf24_read_block */ 512 513static int 514paf24_read (SF_PRIVATE *psf, PAF24_PRIVATE *ppaf24, int *ptr, int len) 515{ int count, total = 0 ; 516 517 while (total < len) 518 { if (ppaf24->read_block * PAF24_SAMPLES_PER_BLOCK >= ppaf24->sample_count) 519 { memset (&(ptr [total]), 0, (len - total) * sizeof (int)) ; 520 return total ; 521 } ; 522 523 if (ppaf24->read_count >= PAF24_SAMPLES_PER_BLOCK) 524 paf24_read_block (psf, ppaf24) ; 525 526 count = (PAF24_SAMPLES_PER_BLOCK - ppaf24->read_count) * ppaf24->channels ; 527 count = (len - total > count) ? count : len - total ; 528 529 memcpy (&(ptr [total]), &(ppaf24->samples [ppaf24->read_count * ppaf24->channels]), count * sizeof (int)) ; 530 total += count ; 531 ppaf24->read_count += count / ppaf24->channels ; 532 } ; 533 534 return total ; 535} /* paf24_read */ 536 537static sf_count_t 538paf24_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) 539{ BUF_UNION ubuf ; 540 PAF24_PRIVATE *ppaf24 ; 541 int *iptr ; 542 int k, bufferlen, readcount, count ; 543 sf_count_t total = 0 ; 544 545 if (psf->codec_data == NULL) 546 return 0 ; 547 ppaf24 = (PAF24_PRIVATE*) psf->codec_data ; 548 549 iptr = ubuf.ibuf ; 550 bufferlen = ARRAY_LEN (ubuf.ibuf) ; 551 while (len > 0) 552 { readcount = (len >= bufferlen) ? bufferlen : (int) len ; 553 count = paf24_read (psf, ppaf24, iptr, readcount) ; 554 for (k = 0 ; k < readcount ; k++) 555 ptr [total + k] = iptr [k] >> 16 ; 556 total += count ; 557 len -= readcount ; 558 } ; 559 return total ; 560} /* paf24_read_s */ 561 562static sf_count_t 563paf24_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) 564{ PAF24_PRIVATE *ppaf24 ; 565 int total ; 566 567 if (psf->codec_data == NULL) 568 return 0 ; 569 ppaf24 = (PAF24_PRIVATE*) psf->codec_data ; 570 571 total = paf24_read (psf, ppaf24, ptr, len) ; 572 573 return total ; 574} /* paf24_read_i */ 575 576static sf_count_t 577paf24_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) 578{ BUF_UNION ubuf ; 579 PAF24_PRIVATE *ppaf24 ; 580 int *iptr ; 581 int k, bufferlen, readcount, count ; 582 sf_count_t total = 0 ; 583 float normfact ; 584 585 if (psf->codec_data == NULL) 586 return 0 ; 587 ppaf24 = (PAF24_PRIVATE*) psf->codec_data ; 588 589 normfact = (psf->norm_float == SF_TRUE) ? (1.0 / 0x80000000) : (1.0 / 0x100) ; 590 591 iptr = ubuf.ibuf ; 592 bufferlen = ARRAY_LEN (ubuf.ibuf) ; 593 while (len > 0) 594 { readcount = (len >= bufferlen) ? bufferlen : (int) len ; 595 count = paf24_read (psf, ppaf24, iptr, readcount) ; 596 for (k = 0 ; k < readcount ; k++) 597 ptr [total + k] = normfact * iptr [k] ; 598 total += count ; 599 len -= readcount ; 600 } ; 601 return total ; 602} /* paf24_read_f */ 603 604static sf_count_t 605paf24_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) 606{ BUF_UNION ubuf ; 607 PAF24_PRIVATE *ppaf24 ; 608 int *iptr ; 609 int k, bufferlen, readcount, count ; 610 sf_count_t total = 0 ; 611 double normfact ; 612 613 if (psf->codec_data == NULL) 614 return 0 ; 615 ppaf24 = (PAF24_PRIVATE*) psf->codec_data ; 616 617 normfact = (psf->norm_double == SF_TRUE) ? (1.0 / 0x80000000) : (1.0 / 0x100) ; 618 619 iptr = ubuf.ibuf ; 620 bufferlen = ARRAY_LEN (ubuf.ibuf) ; 621 while (len > 0) 622 { readcount = (len >= bufferlen) ? bufferlen : (int) len ; 623 count = paf24_read (psf, ppaf24, iptr, readcount) ; 624 for (k = 0 ; k < readcount ; k++) 625 ptr [total + k] = normfact * iptr [k] ; 626 total += count ; 627 len -= readcount ; 628 } ; 629 return total ; 630} /* paf24_read_d */ 631 632/*--------------------------------------------------------------------------- 633*/ 634 635static int 636paf24_write_block (SF_PRIVATE *psf, PAF24_PRIVATE *ppaf24) 637{ int k, nextsample, channel ; 638 unsigned char *cptr ; 639 640 /* First pack block. */ 641 642 if (CPU_IS_LITTLE_ENDIAN) 643 { for (k = 0 ; k < PAF24_SAMPLES_PER_BLOCK * ppaf24->channels ; k++) 644 { channel = k % ppaf24->channels ; 645 cptr = ((unsigned char *) ppaf24->block) + PAF24_BLOCK_SIZE * channel + 3 * (k / ppaf24->channels) ; 646 nextsample = ppaf24->samples [k] >> 8 ; 647 cptr [0] = nextsample ; 648 cptr [1] = nextsample >> 8 ; 649 cptr [2] = nextsample >> 16 ; 650 } ; 651 652 /* Do endian swapping if necessary. */ 653 if (psf->endian == SF_ENDIAN_BIG) 654 endswap_int_array (ppaf24->block, 8 * ppaf24->channels) ; 655 } 656 else if (CPU_IS_BIG_ENDIAN) 657 { /* This is correct. */ 658 for (k = 0 ; k < PAF24_SAMPLES_PER_BLOCK * ppaf24->channels ; k++) 659 { channel = k % ppaf24->channels ; 660 cptr = ((unsigned char *) ppaf24->block) + PAF24_BLOCK_SIZE * channel + 3 * (k / ppaf24->channels) ; 661 nextsample = ppaf24->samples [k] >> 8 ; 662 cptr [0] = nextsample ; 663 cptr [1] = nextsample >> 8 ; 664 cptr [2] = nextsample >> 16 ; 665 } ; 666 if (psf->endian == SF_ENDIAN_LITTLE) 667 endswap_int_array (ppaf24->block, 8 * ppaf24->channels) ; 668 } ; 669 670 /* Write block to disk. */ 671 if ((k = (int) psf_fwrite (ppaf24->block, 1, ppaf24->blocksize, psf)) != ppaf24->blocksize) 672 psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", k, ppaf24->blocksize) ; 673 674 if (ppaf24->sample_count < ppaf24->write_block * PAF24_SAMPLES_PER_BLOCK + ppaf24->write_count) 675 ppaf24->sample_count = ppaf24->write_block * PAF24_SAMPLES_PER_BLOCK + ppaf24->write_count ; 676 677 if (ppaf24->write_count == PAF24_SAMPLES_PER_BLOCK) 678 { ppaf24->write_block ++ ; 679 ppaf24->write_count = 0 ; 680 } ; 681 682 return 1 ; 683} /* paf24_write_block */ 684 685static int 686paf24_write (SF_PRIVATE *psf, PAF24_PRIVATE *ppaf24, const int *ptr, int len) 687{ int count, total = 0 ; 688 689 while (total < len) 690 { count = (PAF24_SAMPLES_PER_BLOCK - ppaf24->write_count) * ppaf24->channels ; 691 692 if (count > len - total) 693 count = len - total ; 694 695 memcpy (&(ppaf24->samples [ppaf24->write_count * ppaf24->channels]), &(ptr [total]), count * sizeof (int)) ; 696 total += count ; 697 ppaf24->write_count += count / ppaf24->channels ; 698 699 if (ppaf24->write_count >= PAF24_SAMPLES_PER_BLOCK) 700 paf24_write_block (psf, ppaf24) ; 701 } ; 702 703 return total ; 704} /* paf24_write */ 705 706static sf_count_t 707paf24_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) 708{ BUF_UNION ubuf ; 709 PAF24_PRIVATE *ppaf24 ; 710 int *iptr ; 711 int k, bufferlen, writecount = 0, count ; 712 sf_count_t total = 0 ; 713 714 if (psf->codec_data == NULL) 715 return 0 ; 716 ppaf24 = (PAF24_PRIVATE*) psf->codec_data ; 717 718 iptr = ubuf.ibuf ; 719 bufferlen = ARRAY_LEN (ubuf.ibuf) ; 720 while (len > 0) 721 { writecount = (len >= bufferlen) ? bufferlen : (int) len ; 722 for (k = 0 ; k < writecount ; k++) 723 iptr [k] = ptr [total + k] << 16 ; 724 count = paf24_write (psf, ppaf24, iptr, writecount) ; 725 total += count ; 726 len -= writecount ; 727 if (count != writecount) 728 break ; 729 } ; 730 return total ; 731} /* paf24_write_s */ 732 733static sf_count_t 734paf24_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) 735{ PAF24_PRIVATE *ppaf24 ; 736 int writecount, count ; 737 sf_count_t total = 0 ; 738 739 if (psf->codec_data == NULL) 740 return 0 ; 741 ppaf24 = (PAF24_PRIVATE*) psf->codec_data ; 742 743 while (len > 0) 744 { writecount = (len > 0x10000000) ? 0x10000000 : (int) len ; 745 746 count = paf24_write (psf, ppaf24, ptr, writecount) ; 747 748 total += count ; 749 len -= count ; 750 if (count != writecount) 751 break ; 752 } ; 753 754 return total ; 755} /* paf24_write_i */ 756 757static sf_count_t 758paf24_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) 759{ BUF_UNION ubuf ; 760 PAF24_PRIVATE *ppaf24 ; 761 int *iptr ; 762 int k, bufferlen, writecount = 0, count ; 763 sf_count_t total = 0 ; 764 float normfact ; 765 766 if (psf->codec_data == NULL) 767 return 0 ; 768 ppaf24 = (PAF24_PRIVATE*) psf->codec_data ; 769 770 normfact = (psf->norm_float == SF_TRUE) ? (1.0 * 0x7FFFFFFF) : (1.0 / 0x100) ; 771 772 iptr = ubuf.ibuf ; 773 bufferlen = ARRAY_LEN (ubuf.ibuf) ; 774 while (len > 0) 775 { writecount = (len >= bufferlen) ? bufferlen : (int) len ; 776 for (k = 0 ; k < writecount ; k++) 777 iptr [k] = psf_lrintf (normfact * ptr [total + k]) ; 778 count = paf24_write (psf, ppaf24, iptr, writecount) ; 779 total += count ; 780 len -= writecount ; 781 if (count != writecount) 782 break ; 783 } ; 784 785 return total ; 786} /* paf24_write_f */ 787 788static sf_count_t 789paf24_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) 790{ BUF_UNION ubuf ; 791 PAF24_PRIVATE *ppaf24 ; 792 int *iptr ; 793 int k, bufferlen, writecount = 0, count ; 794 sf_count_t total = 0 ; 795 double normfact ; 796 797 if (psf->codec_data == NULL) 798 return 0 ; 799 ppaf24 = (PAF24_PRIVATE*) psf->codec_data ; 800 801 normfact = (psf->norm_double == SF_TRUE) ? (1.0 * 0x7FFFFFFF) : (1.0 / 0x100) ; 802 803 iptr = ubuf.ibuf ; 804 bufferlen = ARRAY_LEN (ubuf.ibuf) ; 805 while (len > 0) 806 { writecount = (len >= bufferlen) ? bufferlen : (int) len ; 807 for (k = 0 ; k < writecount ; k++) 808 iptr [k] = psf_lrint (normfact * ptr [total+k]) ; 809 count = paf24_write (psf, ppaf24, iptr, writecount) ; 810 total += count ; 811 len -= writecount ; 812 if (count != writecount) 813 break ; 814 } ; 815 816 return total ; 817} /* paf24_write_d */ 818 819