Coverage Report

Created: 2025-12-14 06:54

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