2 ** Copyright (C) 1999-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
4 ** This program is free software; you can redistribute it and/or modify
5 ** it under the terms of the GNU Lesser General Public License as published by
6 ** the Free Software Foundation; either version 2.1 of the License, or
7 ** (at your option) any later version.
9 ** This program is distributed in the hope that it will be useful,
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 ** GNU Lesser General Public License for more details.
14 ** You should have received a copy of the GNU Lesser General Public License
15 ** along with this program; if not, write to the Free Software
16 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 #if CPU_IS_LITTLE_ENDIAN
32 #define DOUBLE64_READ double64_le_read
33 #define DOUBLE64_WRITE double64_le_write
34 #elif CPU_IS_BIG_ENDIAN
35 #define DOUBLE64_READ double64_be_read
36 #define DOUBLE64_WRITE double64_be_write
39 /* A 32 number which will not overflow when multiplied by sizeof (double). */
40 #define SENSIBLE_LEN (0x8000000)
42 /*--------------------------------------------------------------------------------------------
43 ** Processor floating point capabilities. double64_get_capability () returns one of the
44 ** latter three values.
48 { DOUBLE_UNKNOWN
= 0x00,
49 DOUBLE_CAN_RW_LE
= 0x23,
50 DOUBLE_CAN_RW_BE
= 0x34,
51 DOUBLE_BROKEN_LE
= 0x45,
52 DOUBLE_BROKEN_BE
= 0x56
55 /*--------------------------------------------------------------------------------------------
56 ** Prototypes for private functions.
59 static sf_count_t
host_read_d2s (SF_PRIVATE
*psf
, short *ptr
, sf_count_t len
) ;
60 static sf_count_t
host_read_d2i (SF_PRIVATE
*psf
, int *ptr
, sf_count_t len
) ;
61 static sf_count_t
host_read_d2f (SF_PRIVATE
*psf
, float *ptr
, sf_count_t len
) ;
62 static sf_count_t
host_read_d (SF_PRIVATE
*psf
, double *ptr
, sf_count_t len
) ;
64 static sf_count_t
host_write_s2d (SF_PRIVATE
*psf
, const short *ptr
, sf_count_t len
) ;
65 static sf_count_t
host_write_i2d (SF_PRIVATE
*psf
, const int *ptr
, sf_count_t len
) ;
66 static sf_count_t
host_write_f2d (SF_PRIVATE
*psf
, const float *ptr
, sf_count_t len
) ;
67 static sf_count_t
host_write_d (SF_PRIVATE
*psf
, const double *ptr
, sf_count_t len
) ;
69 static void double64_peak_update (SF_PRIVATE
*psf
, const double *buffer
, int count
, sf_count_t indx
) ;
71 static int double64_get_capability (SF_PRIVATE
*psf
) ;
73 static sf_count_t
replace_read_d2s (SF_PRIVATE
*psf
, short *ptr
, sf_count_t len
) ;
74 static sf_count_t
replace_read_d2i (SF_PRIVATE
*psf
, int *ptr
, sf_count_t len
) ;
75 static sf_count_t
replace_read_d2f (SF_PRIVATE
*psf
, float *ptr
, sf_count_t len
) ;
76 static sf_count_t
replace_read_d (SF_PRIVATE
*psf
, double *ptr
, sf_count_t len
) ;
78 static sf_count_t
replace_write_s2d (SF_PRIVATE
*psf
, const short *ptr
, sf_count_t len
) ;
79 static sf_count_t
replace_write_i2d (SF_PRIVATE
*psf
, const int *ptr
, sf_count_t len
) ;
80 static sf_count_t
replace_write_f2d (SF_PRIVATE
*psf
, const float *ptr
, sf_count_t len
) ;
81 static sf_count_t
replace_write_d (SF_PRIVATE
*psf
, const double *ptr
, sf_count_t len
) ;
83 static void d2bd_read (double *buffer
, int count
) ;
84 static void bd2d_write (double *buffer
, int count
) ;
86 /*--------------------------------------------------------------------------------------------
87 ** Exported functions.
91 double64_init (SF_PRIVATE
*psf
)
92 { static int double64_caps
;
94 double64_caps
= double64_get_capability (psf
) ;
96 psf
->blockwidth
= sizeof (double) * psf
->sf
.channels
;
98 if (psf
->file
.mode
== SFM_READ
|| psf
->file
.mode
== SFM_RDWR
)
99 { switch (psf
->endian
+ double64_caps
)
100 { case (SF_ENDIAN_BIG
+ DOUBLE_CAN_RW_BE
) :
101 psf
->data_endswap
= SF_FALSE
;
102 psf
->read_short
= host_read_d2s
;
103 psf
->read_int
= host_read_d2i
;
104 psf
->read_float
= host_read_d2f
;
105 psf
->read_double
= host_read_d
;
108 case (SF_ENDIAN_LITTLE
+ DOUBLE_CAN_RW_LE
) :
109 psf
->data_endswap
= SF_FALSE
;
110 psf
->read_short
= host_read_d2s
;
111 psf
->read_int
= host_read_d2i
;
112 psf
->read_float
= host_read_d2f
;
113 psf
->read_double
= host_read_d
;
116 case (SF_ENDIAN_BIG
+ DOUBLE_CAN_RW_LE
) :
117 psf
->data_endswap
= SF_TRUE
;
118 psf
->read_short
= host_read_d2s
;
119 psf
->read_int
= host_read_d2i
;
120 psf
->read_float
= host_read_d2f
;
121 psf
->read_double
= host_read_d
;
124 case (SF_ENDIAN_LITTLE
+ DOUBLE_CAN_RW_BE
) :
125 psf
->data_endswap
= SF_TRUE
;
126 psf
->read_short
= host_read_d2s
;
127 psf
->read_int
= host_read_d2i
;
128 psf
->read_float
= host_read_d2f
;
129 psf
->read_double
= host_read_d
;
132 /* When the CPU is not IEEE compatible. */
133 case (SF_ENDIAN_BIG
+ DOUBLE_BROKEN_BE
) :
134 psf
->data_endswap
= SF_FALSE
;
135 psf
->read_short
= replace_read_d2s
;
136 psf
->read_int
= replace_read_d2i
;
137 psf
->read_float
= replace_read_d2f
;
138 psf
->read_double
= replace_read_d
;
141 case (SF_ENDIAN_LITTLE
+ DOUBLE_BROKEN_LE
) :
142 psf
->data_endswap
= SF_FALSE
;
143 psf
->read_short
= replace_read_d2s
;
144 psf
->read_int
= replace_read_d2i
;
145 psf
->read_float
= replace_read_d2f
;
146 psf
->read_double
= replace_read_d
;
149 case (SF_ENDIAN_BIG
+ DOUBLE_BROKEN_LE
) :
150 psf
->data_endswap
= SF_TRUE
;
151 psf
->read_short
= replace_read_d2s
;
152 psf
->read_int
= replace_read_d2i
;
153 psf
->read_float
= replace_read_d2f
;
154 psf
->read_double
= replace_read_d
;
157 case (SF_ENDIAN_LITTLE
+ DOUBLE_BROKEN_BE
) :
158 psf
->data_endswap
= SF_TRUE
;
159 psf
->read_short
= replace_read_d2s
;
160 psf
->read_int
= replace_read_d2i
;
161 psf
->read_float
= replace_read_d2f
;
162 psf
->read_double
= replace_read_d
;
169 if (psf
->file
.mode
== SFM_WRITE
|| psf
->file
.mode
== SFM_RDWR
)
170 { switch (psf
->endian
+ double64_caps
)
171 { case (SF_ENDIAN_LITTLE
+ DOUBLE_CAN_RW_LE
) :
172 psf
->data_endswap
= SF_FALSE
;
173 psf
->write_short
= host_write_s2d
;
174 psf
->write_int
= host_write_i2d
;
175 psf
->write_float
= host_write_f2d
;
176 psf
->write_double
= host_write_d
;
179 case (SF_ENDIAN_BIG
+ DOUBLE_CAN_RW_BE
) :
180 psf
->data_endswap
= SF_FALSE
;
181 psf
->write_short
= host_write_s2d
;
182 psf
->write_int
= host_write_i2d
;
183 psf
->write_float
= host_write_f2d
;
184 psf
->write_double
= host_write_d
;
187 case (SF_ENDIAN_BIG
+ DOUBLE_CAN_RW_LE
) :
188 psf
->data_endswap
= SF_TRUE
;
189 psf
->write_short
= host_write_s2d
;
190 psf
->write_int
= host_write_i2d
;
191 psf
->write_float
= host_write_f2d
;
192 psf
->write_double
= host_write_d
;
195 case (SF_ENDIAN_LITTLE
+ DOUBLE_CAN_RW_BE
) :
196 psf
->data_endswap
= SF_TRUE
;
197 psf
->write_short
= host_write_s2d
;
198 psf
->write_int
= host_write_i2d
;
199 psf
->write_float
= host_write_f2d
;
200 psf
->write_double
= host_write_d
;
203 /* When the CPU is not IEEE compatible. */
204 case (SF_ENDIAN_LITTLE
+ DOUBLE_BROKEN_LE
) :
205 psf
->data_endswap
= SF_FALSE
;
206 psf
->write_short
= replace_write_s2d
;
207 psf
->write_int
= replace_write_i2d
;
208 psf
->write_float
= replace_write_f2d
;
209 psf
->write_double
= replace_write_d
;
212 case (SF_ENDIAN_BIG
+ DOUBLE_BROKEN_BE
) :
213 psf
->data_endswap
= SF_FALSE
;
214 psf
->write_short
= replace_write_s2d
;
215 psf
->write_int
= replace_write_i2d
;
216 psf
->write_float
= replace_write_f2d
;
217 psf
->write_double
= replace_write_d
;
220 case (SF_ENDIAN_BIG
+ DOUBLE_BROKEN_LE
) :
221 psf
->data_endswap
= SF_TRUE
;
222 psf
->write_short
= replace_write_s2d
;
223 psf
->write_int
= replace_write_i2d
;
224 psf
->write_float
= replace_write_f2d
;
225 psf
->write_double
= replace_write_d
;
228 case (SF_ENDIAN_LITTLE
+ DOUBLE_BROKEN_BE
) :
229 psf
->data_endswap
= SF_TRUE
;
230 psf
->write_short
= replace_write_s2d
;
231 psf
->write_int
= replace_write_i2d
;
232 psf
->write_float
= replace_write_f2d
;
233 psf
->write_double
= replace_write_d
;
240 if (psf
->filelength
> psf
->dataoffset
)
241 { psf
->datalength
= (psf
->dataend
> 0) ? psf
->dataend
- psf
->dataoffset
:
242 psf
->filelength
- psf
->dataoffset
;
245 psf
->datalength
= 0 ;
247 psf
->sf
.frames
= psf
->datalength
/ psf
->blockwidth
;
250 } /* double64_init */
252 /*----------------------------------------------------------------------------
253 ** From : http://www.hpcf.cam.ac.uk/fp_formats.html
255 ** 64 bit double precision layout (big endian)
257 ** Exponent bits 1-11
258 ** Mantissa bits 12-63
259 ** Exponent Offset 1023
263 ** +INF 7FF0000000000000 7F800000
264 ** -INF FFF0000000000000 FF800000
265 ** NaN 7FF0000000000001 7F800001
267 ** 7FFFFFFFFFFFFFFF 7FFFFFFF
269 ** FFF0000000000001 FF800001
271 ** FFFFFFFFFFFFFFFF FFFFFFFF
272 ** +OVER 7FEFFFFFFFFFFFFF 7F7FFFFF
273 ** -OVER FFEFFFFFFFFFFFFF FF7FFFFF
274 ** +UNDER 0010000000000000 00800000
275 ** -UNDER 8010000000000000 80800000
279 double64_be_read (unsigned char *cptr
)
280 { int exponent
, negative
, upper
, lower
;
283 negative
= (cptr
[0] & 0x80) ? 1 : 0 ;
284 exponent
= ((cptr
[0] & 0x7F) << 4) | ((cptr
[1] >> 4) & 0xF) ;
286 /* Might not have a 64 bit long, so load the mantissa into a double. */
287 upper
= (((cptr
[1] & 0xF) << 24) | (cptr
[2] << 16) | (cptr
[3] << 8) | cptr
[4]) ;
288 lower
= (cptr
[5] << 16) | (cptr
[6] << 8) | cptr
[7] ;
290 if (exponent
== 0 && upper
== 0 && lower
== 0)
293 dvalue
= upper
+ lower
/ ((double) 0x1000000) ;
294 dvalue
+= 0x10000000 ;
296 exponent
= exponent
- 0x3FF ;
298 dvalue
= dvalue
/ ((double) 0x10000000) ;
304 dvalue
*= pow (2.0, exponent
) ;
305 else if (exponent
< 0)
306 dvalue
/= pow (2.0, abs (exponent
)) ;
309 } /* double64_be_read */
312 double64_le_read (unsigned char *cptr
)
313 { int exponent
, negative
, upper
, lower
;
316 negative
= (cptr
[7] & 0x80) ? 1 : 0 ;
317 exponent
= ((cptr
[7] & 0x7F) << 4) | ((cptr
[6] >> 4) & 0xF) ;
319 /* Might not have a 64 bit long, so load the mantissa into a double. */
320 upper
= ((cptr
[6] & 0xF) << 24) | (cptr
[5] << 16) | (cptr
[4] << 8) | cptr
[3] ;
321 lower
= (cptr
[2] << 16) | (cptr
[1] << 8) | cptr
[0] ;
323 if (exponent
== 0 && upper
== 0 && lower
== 0)
326 dvalue
= upper
+ lower
/ ((double) 0x1000000) ;
327 dvalue
+= 0x10000000 ;
329 exponent
= exponent
- 0x3FF ;
331 dvalue
= dvalue
/ ((double) 0x10000000) ;
337 dvalue
*= pow (2.0, exponent
) ;
338 else if (exponent
< 0)
339 dvalue
/= pow (2.0, abs (exponent
)) ;
342 } /* double64_le_read */
345 double64_be_write (double in
, unsigned char *out
)
346 { int exponent
, mantissa
;
348 memset (out
, 0, sizeof (double)) ;
350 if (fabs (in
) < 1e-30)
358 in
= frexp (in
, &exponent
) ;
362 out
[0] |= (exponent
>> 4) & 0x7F ;
363 out
[1] |= (exponent
<< 4) & 0xF0 ;
366 mantissa
= lrint (floor (in
)) ;
368 out
[1] |= (mantissa
>> 24) & 0xF ;
369 out
[2] = (mantissa
>> 16) & 0xFF ;
370 out
[3] = (mantissa
>> 8) & 0xFF ;
371 out
[4] = mantissa
& 0xFF ;
373 in
= fmod (in
, 1.0) ;
375 mantissa
= lrint (floor (in
)) ;
377 out
[5] = (mantissa
>> 16) & 0xFF ;
378 out
[6] = (mantissa
>> 8) & 0xFF ;
379 out
[7] = mantissa
& 0xFF ;
382 } /* double64_be_write */
385 double64_le_write (double in
, unsigned char *out
)
386 { int exponent
, mantissa
;
388 memset (out
, 0, sizeof (double)) ;
390 if (fabs (in
) < 1e-30)
398 in
= frexp (in
, &exponent
) ;
402 out
[7] |= (exponent
>> 4) & 0x7F ;
403 out
[6] |= (exponent
<< 4) & 0xF0 ;
406 mantissa
= lrint (floor (in
)) ;
408 out
[6] |= (mantissa
>> 24) & 0xF ;
409 out
[5] = (mantissa
>> 16) & 0xFF ;
410 out
[4] = (mantissa
>> 8) & 0xFF ;
411 out
[3] = mantissa
& 0xFF ;
413 in
= fmod (in
, 1.0) ;
415 mantissa
= lrint (floor (in
)) ;
417 out
[2] = (mantissa
>> 16) & 0xFF ;
418 out
[1] = (mantissa
>> 8) & 0xFF ;
419 out
[0] = mantissa
& 0xFF ;
422 } /* double64_le_write */
424 /*==============================================================================================
425 ** Private functions.
429 double64_peak_update (SF_PRIVATE
*psf
, const double *buffer
, int count
, sf_count_t indx
)
434 for (chan
= 0 ; chan
< psf
->sf
.channels
; chan
++)
435 { fmaxval
= fabs (buffer
[chan
]) ;
437 for (k
= chan
; k
< count
; k
+= psf
->sf
.channels
)
438 if (fmaxval
< fabs (buffer
[k
]))
439 { fmaxval
= fabs (buffer
[k
]) ;
443 if (fmaxval
> psf
->peak_info
->peaks
[chan
].value
)
444 { psf
->peak_info
->peaks
[chan
].value
= fmaxval
;
445 psf
->peak_info
->peaks
[chan
].position
= psf
->write_current
+ indx
+ (position
/ psf
->sf
.channels
) ;
450 } /* double64_peak_update */
453 double64_get_capability (SF_PRIVATE
*psf
)
456 unsigned char c
[8] ;
459 data
.d
= 1.234567890123456789 ; /* Some abitrary value. */
461 if (! psf
->ieee_replace
)
462 { /* If this test is true ints and floats are compatible and little endian. */
463 if (data
.c
[0] == 0xfb && data
.c
[1] == 0x59 && data
.c
[2] == 0x8c && data
.c
[3] == 0x42 &&
464 data
.c
[4] == 0xca && data
.c
[5] == 0xc0 && data
.c
[6] == 0xf3 && data
.c
[7] == 0x3f)
465 return DOUBLE_CAN_RW_LE
;
467 /* If this test is true ints and floats are compatible and big endian. */
468 if (data
.c
[0] == 0x3f && data
.c
[1] == 0xf3 && data
.c
[2] == 0xc0 && data
.c
[3] == 0xca &&
469 data
.c
[4] == 0x42 && data
.c
[5] == 0x8c && data
.c
[6] == 0x59 && data
.c
[7] == 0xfb)
470 return DOUBLE_CAN_RW_BE
;
473 /* Doubles are broken. Don't expect reading or writing to be fast. */
474 psf_log_printf (psf
, "Using IEEE replacement code for double.\n") ;
476 return (CPU_IS_LITTLE_ENDIAN
) ? DOUBLE_BROKEN_LE
: DOUBLE_BROKEN_BE
;
477 } /* double64_get_capability */
479 /*=======================================================================================
483 d2s_array (const double *src
, int count
, short *dest
, double scale
)
484 { while (--count
>= 0)
485 { dest
[count
] = lrint (scale
* src
[count
]) ;
490 d2s_clip_array (const double *src
, int count
, short *dest
, double scale
)
491 { while (--count
>= 0)
492 { double tmp
= scale
* src
[count
] ;
494 if (CPU_CLIPS_POSITIVE
== 0 && tmp
> 32767.0)
495 dest
[count
] = SHRT_MAX
;
496 else if (CPU_CLIPS_NEGATIVE
== 0 && tmp
< -32768.0)
497 dest
[count
] = SHRT_MIN
;
499 dest
[count
] = lrint (tmp
) ;
501 } /* d2s_clip_array */
504 d2i_array (const double *src
, int count
, int *dest
, double scale
)
505 { while (--count
>= 0)
506 { dest
[count
] = lrint (scale
* src
[count
]) ;
511 d2i_clip_array (const double *src
, int count
, int *dest
, double scale
)
512 { while (--count
>= 0)
513 { float tmp
= scale
* src
[count
] ;
515 if (CPU_CLIPS_POSITIVE
== 0 && tmp
> (1.0 * INT_MAX
))
516 dest
[count
] = INT_MAX
;
517 else if (CPU_CLIPS_NEGATIVE
== 0 && tmp
< (-1.0 * INT_MAX
))
518 dest
[count
] = INT_MIN
;
520 dest
[count
] = lrint (tmp
) ;
522 } /* d2i_clip_array */
525 d2f_array (const double *src
, int count
, float *dest
)
526 { while (--count
>= 0)
527 { dest
[count
] = src
[count
] ;
532 s2d_array (const short *src
, double *dest
, int count
, double scale
)
533 { while (--count
>= 0)
534 { dest
[count
] = scale
* src
[count
] ;
539 i2d_array (const int *src
, double *dest
, int count
, double scale
)
540 { while (--count
>= 0)
541 { dest
[count
] = scale
* src
[count
] ;
546 f2d_array (const float *src
, double *dest
, int count
)
547 { while (--count
>= 0)
548 { dest
[count
] = src
[count
] ;
552 /*----------------------------------------------------------------------------------------------
556 host_read_d2s (SF_PRIVATE
*psf
, short *ptr
, sf_count_t len
)
557 { void (*convert
) (const double *, int, short *, double) ;
558 int bufferlen
, readcount
;
559 sf_count_t total
= 0 ;
562 convert
= (psf
->add_clipping
) ? d2s_clip_array
: d2s_array
;
563 bufferlen
= ARRAY_LEN (psf
->u
.dbuf
) ;
564 scale
= (psf
->float_int_mult
== 0) ? 1.0 : 0x7FFF / psf
->float_max
;
567 { if (len
< bufferlen
)
568 bufferlen
= (int) len
;
569 readcount
= psf_fread (psf
->u
.dbuf
, sizeof (double), bufferlen
, psf
) ;
571 if (psf
->data_endswap
== SF_TRUE
)
572 endswap_double_array (psf
->u
.dbuf
, readcount
) ;
574 convert (psf
->u
.dbuf
, readcount
, ptr
+ total
, scale
) ;
577 if (readcount
< bufferlen
)
582 } /* host_read_d2s */
585 host_read_d2i (SF_PRIVATE
*psf
, int *ptr
, sf_count_t len
)
586 { void (*convert
) (const double *, int, int *, double) ;
587 int bufferlen
, readcount
;
588 sf_count_t total
= 0 ;
591 convert
= (psf
->add_clipping
) ? d2i_clip_array
: d2i_array
;
592 bufferlen
= ARRAY_LEN (psf
->u
.dbuf
) ;
593 scale
= (psf
->float_int_mult
== 0) ? 1.0 : 0x7FFFFFFF / psf
->float_max
;
596 { if (len
< bufferlen
)
597 bufferlen
= (int) len
;
598 readcount
= psf_fread (psf
->u
.dbuf
, sizeof (double), bufferlen
, psf
) ;
600 if (psf
->data_endswap
== SF_TRUE
)
601 endswap_double_array (psf
->u
.dbuf
, bufferlen
) ;
603 convert (psf
->u
.dbuf
, readcount
, ptr
+ total
, scale
) ;
606 if (readcount
< bufferlen
)
611 } /* host_read_d2i */
614 host_read_d2f (SF_PRIVATE
*psf
, float *ptr
, sf_count_t len
)
615 { int bufferlen
, readcount
;
616 sf_count_t total
= 0 ;
618 bufferlen
= ARRAY_LEN (psf
->u
.dbuf
) ;
621 { if (len
< bufferlen
)
622 bufferlen
= (int) len
;
623 readcount
= psf_fread (psf
->u
.dbuf
, sizeof (double), bufferlen
, psf
) ;
625 if (psf
->data_endswap
== SF_TRUE
)
626 endswap_double_array (psf
->u
.dbuf
, bufferlen
) ;
628 d2f_array (psf
->u
.dbuf
, readcount
, ptr
+ total
) ;
631 if (readcount
< bufferlen
)
636 } /* host_read_d2f */
639 host_read_d (SF_PRIVATE
*psf
, double *ptr
, sf_count_t len
)
641 sf_count_t readcount
, total
= 0 ;
643 readcount
= psf_fread (ptr
, sizeof (double), len
, psf
) ;
645 if (psf
->data_endswap
!= SF_TRUE
)
648 /* If the read length was sensible, endswap output in one go. */
649 if (readcount
< SENSIBLE_LEN
)
650 { endswap_double_array (ptr
, readcount
) ;
654 bufferlen
= SENSIBLE_LEN
;
656 { if (len
< bufferlen
)
657 bufferlen
= (int) len
;
659 endswap_double_array (ptr
+ total
, bufferlen
) ;
669 host_write_s2d (SF_PRIVATE
*psf
, const short *ptr
, sf_count_t len
)
670 { int bufferlen
, writecount
;
671 sf_count_t total
= 0 ;
674 scale
= (psf
->scale_int_float
== 0) ? 1.0 : 1.0 / 0x8000 ;
675 bufferlen
= ARRAY_LEN (psf
->u
.dbuf
) ;
678 { if (len
< bufferlen
)
679 bufferlen
= (int) len
;
681 s2d_array (ptr
+ total
, psf
->u
.dbuf
, bufferlen
, scale
) ;
684 double64_peak_update (psf
, psf
->u
.dbuf
, bufferlen
, total
/ psf
->sf
.channels
) ;
686 if (psf
->data_endswap
== SF_TRUE
)
687 endswap_double_array (psf
->u
.dbuf
, bufferlen
) ;
689 writecount
= psf_fwrite (psf
->u
.dbuf
, sizeof (double), bufferlen
, psf
) ;
690 total
+= writecount
;
691 if (writecount
< bufferlen
)
697 } /* host_write_s2d */
700 host_write_i2d (SF_PRIVATE
*psf
, const int *ptr
, sf_count_t len
)
701 { int bufferlen
, writecount
;
702 sf_count_t total
= 0 ;
705 scale
= (psf
->scale_int_float
== 0) ? 1.0 : 1.0 / (8.0 * 0x10000000) ;
706 bufferlen
= ARRAY_LEN (psf
->u
.dbuf
) ;
709 { if (len
< bufferlen
)
710 bufferlen
= (int) len
;
711 i2d_array (ptr
+ total
, psf
->u
.dbuf
, bufferlen
, scale
) ;
714 double64_peak_update (psf
, psf
->u
.dbuf
, bufferlen
, total
/ psf
->sf
.channels
) ;
716 if (psf
->data_endswap
== SF_TRUE
)
717 endswap_double_array (psf
->u
.dbuf
, bufferlen
) ;
719 writecount
= psf_fwrite (psf
->u
.dbuf
, sizeof (double), bufferlen
, psf
) ;
720 total
+= writecount
;
721 if (writecount
< bufferlen
)
727 } /* host_write_i2d */
730 host_write_f2d (SF_PRIVATE
*psf
, const float *ptr
, sf_count_t len
)
731 { int bufferlen
, writecount
;
732 sf_count_t total
= 0 ;
734 bufferlen
= ARRAY_LEN (psf
->u
.dbuf
) ;
737 { if (len
< bufferlen
)
738 bufferlen
= (int) len
;
739 f2d_array (ptr
+ total
, psf
->u
.dbuf
, bufferlen
) ;
742 double64_peak_update (psf
, psf
->u
.dbuf
, bufferlen
, total
/ psf
->sf
.channels
) ;
744 if (psf
->data_endswap
== SF_TRUE
)
745 endswap_double_array (psf
->u
.dbuf
, bufferlen
) ;
747 writecount
= psf_fwrite (psf
->u
.dbuf
, sizeof (double), bufferlen
, psf
) ;
748 total
+= writecount
;
749 if (writecount
< bufferlen
)
755 } /* host_write_f2d */
758 host_write_d (SF_PRIVATE
*psf
, const double *ptr
, sf_count_t len
)
759 { int bufferlen
, writecount
;
760 sf_count_t total
= 0 ;
763 double64_peak_update (psf
, ptr
, len
, 0) ;
765 if (psf
->data_endswap
!= SF_TRUE
)
766 return psf_fwrite (ptr
, sizeof (double), len
, psf
) ;
768 bufferlen
= ARRAY_LEN (psf
->u
.dbuf
) ;
771 { if (len
< bufferlen
)
772 bufferlen
= (int) len
;
774 endswap_double_copy (psf
->u
.dbuf
, ptr
+ total
, bufferlen
) ;
776 writecount
= psf_fwrite (psf
->u
.dbuf
, sizeof (double), bufferlen
, psf
) ;
777 total
+= writecount
;
778 if (writecount
< bufferlen
)
786 /*=======================================================================================
790 replace_read_d2s (SF_PRIVATE
*psf
, short *ptr
, sf_count_t len
)
791 { int bufferlen
, readcount
;
792 sf_count_t total
= 0 ;
795 bufferlen
= ARRAY_LEN (psf
->u
.dbuf
) ;
796 scale
= (psf
->float_int_mult
== 0) ? 1.0 : 0x7FFF / psf
->float_max
;
799 { if (len
< bufferlen
)
800 bufferlen
= (int) len
;
801 readcount
= psf_fread (psf
->u
.dbuf
, sizeof (double), bufferlen
, psf
) ;
803 if (psf
->data_endswap
== SF_TRUE
)
804 endswap_double_array (psf
->u
.dbuf
, bufferlen
) ;
806 d2bd_read (psf
->u
.dbuf
, bufferlen
) ;
808 d2s_array (psf
->u
.dbuf
, readcount
, ptr
+ total
, scale
) ;
810 if (readcount
< bufferlen
)
816 } /* replace_read_d2s */
819 replace_read_d2i (SF_PRIVATE
*psf
, int *ptr
, sf_count_t len
)
820 { int bufferlen
, readcount
;
821 sf_count_t total
= 0 ;
824 bufferlen
= ARRAY_LEN (psf
->u
.dbuf
) ;
825 scale
= (psf
->float_int_mult
== 0) ? 1.0 : 0x7FFFFFFF / psf
->float_max
;
828 { if (len
< bufferlen
)
829 bufferlen
= (int) len
;
830 readcount
= psf_fread (psf
->u
.dbuf
, sizeof (double), bufferlen
, psf
) ;
832 if (psf
->data_endswap
== SF_TRUE
)
833 endswap_double_array (psf
->u
.dbuf
, bufferlen
) ;
835 d2bd_read (psf
->u
.dbuf
, bufferlen
) ;
837 d2i_array (psf
->u
.dbuf
, readcount
, ptr
+ total
, scale
) ;
839 if (readcount
< bufferlen
)
845 } /* replace_read_d2i */
848 replace_read_d2f (SF_PRIVATE
*psf
, float *ptr
, sf_count_t len
)
849 { int bufferlen
, readcount
;
850 sf_count_t total
= 0 ;
852 bufferlen
= ARRAY_LEN (psf
->u
.dbuf
) ;
855 { if (len
< bufferlen
)
856 bufferlen
= (int) len
;
857 readcount
= psf_fread (psf
->u
.dbuf
, sizeof (double), bufferlen
, psf
) ;
859 if (psf
->data_endswap
== SF_TRUE
)
860 endswap_double_array (psf
->u
.dbuf
, bufferlen
) ;
862 d2bd_read (psf
->u
.dbuf
, bufferlen
) ;
864 memcpy (ptr
+ total
, psf
->u
.dbuf
, bufferlen
* sizeof (double)) ;
867 if (readcount
< bufferlen
)
873 } /* replace_read_d2f */
876 replace_read_d (SF_PRIVATE
*psf
, double *ptr
, sf_count_t len
)
877 { int bufferlen
, readcount
;
878 sf_count_t total
= 0 ;
880 /* FIXME : This is probably nowhere near optimal. */
881 bufferlen
= ARRAY_LEN (psf
->u
.dbuf
) ;
884 { if (len
< bufferlen
)
885 bufferlen
= (int) len
;
886 readcount
= psf_fread (psf
->u
.dbuf
, sizeof (double), bufferlen
, psf
) ;
888 if (psf
->data_endswap
== SF_TRUE
)
889 endswap_double_array (psf
->u
.dbuf
, readcount
) ;
891 d2bd_read (psf
->u
.dbuf
, readcount
) ;
893 memcpy (ptr
+ total
, psf
->u
.dbuf
, readcount
* sizeof (double)) ;
896 if (readcount
< bufferlen
)
902 } /* replace_read_d */
905 replace_write_s2d (SF_PRIVATE
*psf
, const short *ptr
, sf_count_t len
)
906 { int bufferlen
, writecount
;
907 sf_count_t total
= 0 ;
910 scale
= (psf
->scale_int_float
== 0) ? 1.0 : 1.0 / 0x8000 ;
911 bufferlen
= ARRAY_LEN (psf
->u
.dbuf
) ;
914 { if (len
< bufferlen
)
915 bufferlen
= (int) len
;
916 s2d_array (ptr
+ total
, psf
->u
.dbuf
, bufferlen
, scale
) ;
919 double64_peak_update (psf
, psf
->u
.dbuf
, bufferlen
, total
/ psf
->sf
.channels
) ;
921 bd2d_write (psf
->u
.dbuf
, bufferlen
) ;
923 if (psf
->data_endswap
== SF_TRUE
)
924 endswap_double_array (psf
->u
.dbuf
, bufferlen
) ;
926 writecount
= psf_fwrite (psf
->u
.dbuf
, sizeof (double), bufferlen
, psf
) ;
927 total
+= writecount
;
928 if (writecount
< bufferlen
)
934 } /* replace_write_s2d */
937 replace_write_i2d (SF_PRIVATE
*psf
, const int *ptr
, sf_count_t len
)
938 { int bufferlen
, writecount
;
939 sf_count_t total
= 0 ;
942 scale
= (psf
->scale_int_float
== 0) ? 1.0 : 1.0 / (8.0 * 0x10000000) ;
943 bufferlen
= ARRAY_LEN (psf
->u
.dbuf
) ;
946 { if (len
< bufferlen
)
947 bufferlen
= (int) len
;
948 i2d_array (ptr
+ total
, psf
->u
.dbuf
, bufferlen
, scale
) ;
951 double64_peak_update (psf
, psf
->u
.dbuf
, bufferlen
, total
/ psf
->sf
.channels
) ;
953 bd2d_write (psf
->u
.dbuf
, bufferlen
) ;
955 if (psf
->data_endswap
== SF_TRUE
)
956 endswap_double_array (psf
->u
.dbuf
, bufferlen
) ;
958 writecount
= psf_fwrite (psf
->u
.dbuf
, sizeof (double), bufferlen
, psf
) ;
959 total
+= writecount
;
960 if (writecount
< bufferlen
)
966 } /* replace_write_i2d */
969 replace_write_f2d (SF_PRIVATE
*psf
, const float *ptr
, sf_count_t len
)
970 { int bufferlen
, writecount
;
971 sf_count_t total
= 0 ;
973 bufferlen
= ARRAY_LEN (psf
->u
.dbuf
) ;
976 { if (len
< bufferlen
)
977 bufferlen
= (int) len
;
978 f2d_array (ptr
+ total
, psf
->u
.dbuf
, bufferlen
) ;
980 bd2d_write (psf
->u
.dbuf
, bufferlen
) ;
982 if (psf
->data_endswap
== SF_TRUE
)
983 endswap_double_array (psf
->u
.dbuf
, bufferlen
) ;
985 writecount
= psf_fwrite (psf
->u
.dbuf
, sizeof (double), bufferlen
, psf
) ;
986 total
+= writecount
;
987 if (writecount
< bufferlen
)
993 } /* replace_write_f2d */
996 replace_write_d (SF_PRIVATE
*psf
, const double *ptr
, sf_count_t len
)
997 { int bufferlen
, writecount
;
998 sf_count_t total
= 0 ;
1000 /* FIXME : This is probably nowhere near optimal. */
1002 double64_peak_update (psf
, ptr
, len
, 0) ;
1004 bufferlen
= ARRAY_LEN (psf
->u
.dbuf
) ;
1007 { if (len
< bufferlen
)
1008 bufferlen
= (int) len
;
1010 memcpy (psf
->u
.dbuf
, ptr
+ total
, bufferlen
* sizeof (double)) ;
1012 bd2d_write (psf
->u
.dbuf
, bufferlen
) ;
1014 if (psf
->data_endswap
== SF_TRUE
)
1015 endswap_double_array (psf
->u
.dbuf
, bufferlen
) ;
1017 writecount
= psf_fwrite (psf
->u
.dbuf
, sizeof (double), bufferlen
, psf
) ;
1018 total
+= writecount
;
1019 if (writecount
< bufferlen
)
1025 } /* replace_write_d */
1027 /*----------------------------------------------------------------------------------------------
1031 d2bd_read (double *buffer
, int count
)
1032 { while (--count
>= 0)
1033 { buffer
[count
] = DOUBLE64_READ ((unsigned char *) (buffer
+ count
)) ;
1038 bd2d_write (double *buffer
, int count
)
1039 { while (--count
>= 0)
1040 { DOUBLE64_WRITE (buffer
[count
], (unsigned char*) (buffer
+ count
)) ;