2 ** Copyright (C) 1999-2005 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.
28 #include "float_cast.h"
30 #if CPU_IS_LITTLE_ENDIAN
31 #define DOUBLE64_READ double64_le_read
32 #define DOUBLE64_WRITE double64_le_write
33 #elif CPU_IS_BIG_ENDIAN
34 #define DOUBLE64_READ double64_be_read
35 #define DOUBLE64_WRITE double64_be_write
38 /* A 32 number which will not overflow when multiplied by sizeof (double). */
39 #define SENSIBLE_LEN (0x8000000)
41 /*--------------------------------------------------------------------------------------------
42 ** Processor floating point capabilities. double64_get_capability () returns one of the
43 ** latter three values.
47 { DOUBLE_UNKNOWN = 0x00,
48 DOUBLE_CAN_RW_LE = 0x23,
49 DOUBLE_CAN_RW_BE = 0x34,
50 DOUBLE_BROKEN_LE = 0x45,
51 DOUBLE_BROKEN_BE = 0x56
54 /*--------------------------------------------------------------------------------------------
55 ** Prototypes for private functions.
58 static sf_count_t host_read_d2s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
59 static sf_count_t host_read_d2i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
60 static sf_count_t host_read_d2f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
61 static sf_count_t host_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
63 static sf_count_t host_write_s2d (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
64 static sf_count_t host_write_i2d (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
65 static sf_count_t host_write_f2d (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
66 static sf_count_t host_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
68 static void double64_peak_update (SF_PRIVATE *psf, const double *buffer, int count, sf_count_t indx) ;
70 static int double64_get_capability (SF_PRIVATE *psf) ;
72 static sf_count_t replace_read_d2s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
73 static sf_count_t replace_read_d2i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
74 static sf_count_t replace_read_d2f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
75 static sf_count_t replace_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
77 static sf_count_t replace_write_s2d (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
78 static sf_count_t replace_write_i2d (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
79 static sf_count_t replace_write_f2d (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
80 static sf_count_t replace_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
82 static void d2bd_read (double *buffer, int count) ;
83 static void bd2d_write (double *buffer, int count) ;
85 /*--------------------------------------------------------------------------------------------
86 ** Exported functions.
90 double64_init (SF_PRIVATE *psf)
91 { static int double64_caps ;
93 double64_caps = double64_get_capability (psf) ;
95 psf->blockwidth = sizeof (double) * psf->sf.channels ;
97 if (psf->mode == SFM_READ || psf->mode == SFM_RDWR)
98 { switch (psf->endian + double64_caps)
99 { case (SF_ENDIAN_BIG + DOUBLE_CAN_RW_BE) :
100 psf->float_endswap = SF_FALSE ;
101 psf->read_short = host_read_d2s ;
102 psf->read_int = host_read_d2i ;
103 psf->read_float = host_read_d2f ;
104 psf->read_double = host_read_d ;
107 case (SF_ENDIAN_LITTLE + DOUBLE_CAN_RW_LE) :
108 psf->float_endswap = SF_FALSE ;
109 psf->read_short = host_read_d2s ;
110 psf->read_int = host_read_d2i ;
111 psf->read_float = host_read_d2f ;
112 psf->read_double = host_read_d ;
115 case (SF_ENDIAN_BIG + DOUBLE_CAN_RW_LE) :
116 psf->float_endswap = SF_TRUE ;
117 psf->read_short = host_read_d2s ;
118 psf->read_int = host_read_d2i ;
119 psf->read_float = host_read_d2f ;
120 psf->read_double = host_read_d ;
123 case (SF_ENDIAN_LITTLE + DOUBLE_CAN_RW_BE) :
124 psf->float_endswap = SF_TRUE ;
125 psf->read_short = host_read_d2s ;
126 psf->read_int = host_read_d2i ;
127 psf->read_float = host_read_d2f ;
128 psf->read_double = host_read_d ;
131 /* When the CPU is not IEEE compatible. */
132 case (SF_ENDIAN_BIG + DOUBLE_BROKEN_BE) :
133 psf->float_endswap = SF_FALSE ;
134 psf->read_short = replace_read_d2s ;
135 psf->read_int = replace_read_d2i ;
136 psf->read_float = replace_read_d2f ;
137 psf->read_double = replace_read_d ;
140 case (SF_ENDIAN_LITTLE + DOUBLE_BROKEN_LE) :
141 psf->float_endswap = SF_FALSE ;
142 psf->read_short = replace_read_d2s ;
143 psf->read_int = replace_read_d2i ;
144 psf->read_float = replace_read_d2f ;
145 psf->read_double = replace_read_d ;
148 case (SF_ENDIAN_BIG + DOUBLE_BROKEN_LE) :
149 psf->float_endswap = SF_TRUE ;
150 psf->read_short = replace_read_d2s ;
151 psf->read_int = replace_read_d2i ;
152 psf->read_float = replace_read_d2f ;
153 psf->read_double = replace_read_d ;
156 case (SF_ENDIAN_LITTLE + DOUBLE_BROKEN_BE) :
157 psf->float_endswap = SF_TRUE ;
158 psf->read_short = replace_read_d2s ;
159 psf->read_int = replace_read_d2i ;
160 psf->read_float = replace_read_d2f ;
161 psf->read_double = replace_read_d ;
168 if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
169 { switch (psf->endian + double64_caps)
170 { case (SF_ENDIAN_LITTLE + DOUBLE_CAN_RW_LE) :
171 psf->float_endswap = SF_FALSE ;
172 psf->write_short = host_write_s2d ;
173 psf->write_int = host_write_i2d ;
174 psf->write_float = host_write_f2d ;
175 psf->write_double = host_write_d ;
178 case (SF_ENDIAN_BIG + DOUBLE_CAN_RW_BE) :
179 psf->float_endswap = SF_FALSE ;
180 psf->write_short = host_write_s2d ;
181 psf->write_int = host_write_i2d ;
182 psf->write_float = host_write_f2d ;
183 psf->write_double = host_write_d ;
186 case (SF_ENDIAN_BIG + DOUBLE_CAN_RW_LE) :
187 psf->float_endswap = SF_TRUE ;
188 psf->write_short = host_write_s2d ;
189 psf->write_int = host_write_i2d ;
190 psf->write_float = host_write_f2d ;
191 psf->write_double = host_write_d ;
194 case (SF_ENDIAN_LITTLE + DOUBLE_CAN_RW_BE) :
195 psf->float_endswap = SF_TRUE ;
196 psf->write_short = host_write_s2d ;
197 psf->write_int = host_write_i2d ;
198 psf->write_float = host_write_f2d ;
199 psf->write_double = host_write_d ;
202 /* When the CPU is not IEEE compatible. */
203 case (SF_ENDIAN_LITTLE + DOUBLE_BROKEN_LE) :
204 psf->float_endswap = SF_FALSE ;
205 psf->write_short = replace_write_s2d ;
206 psf->write_int = replace_write_i2d ;
207 psf->write_float = replace_write_f2d ;
208 psf->write_double = replace_write_d ;
211 case (SF_ENDIAN_BIG + DOUBLE_BROKEN_BE) :
212 psf->float_endswap = SF_FALSE ;
213 psf->write_short = replace_write_s2d ;
214 psf->write_int = replace_write_i2d ;
215 psf->write_float = replace_write_f2d ;
216 psf->write_double = replace_write_d ;
219 case (SF_ENDIAN_BIG + DOUBLE_BROKEN_LE) :
220 psf->float_endswap = SF_TRUE ;
221 psf->write_short = replace_write_s2d ;
222 psf->write_int = replace_write_i2d ;
223 psf->write_float = replace_write_f2d ;
224 psf->write_double = replace_write_d ;
227 case (SF_ENDIAN_LITTLE + DOUBLE_BROKEN_BE) :
228 psf->float_endswap = SF_TRUE ;
229 psf->write_short = replace_write_s2d ;
230 psf->write_int = replace_write_i2d ;
231 psf->write_float = replace_write_f2d ;
232 psf->write_double = replace_write_d ;
239 if (psf->filelength > psf->dataoffset)
240 { psf->datalength = (psf->dataend > 0) ? psf->dataend - psf->dataoffset :
241 psf->filelength - psf->dataoffset ;
244 psf->datalength = 0 ;
246 psf->sf.frames = psf->datalength / psf->blockwidth ;
249 } /* double64_init */
251 /*----------------------------------------------------------------------------
252 ** From : http://www.hpcf.cam.ac.uk/fp_formats.html
254 ** 64 bit double precision layout (big endian)
256 ** Exponent bits 1-11
257 ** Mantissa bits 12-63
258 ** Exponent Offset 1023
262 ** +INF 7FF0000000000000 7F800000
263 ** -INF FFF0000000000000 FF800000
264 ** NaN 7FF0000000000001 7F800001
266 ** 7FFFFFFFFFFFFFFF 7FFFFFFF
268 ** FFF0000000000001 FF800001
270 ** FFFFFFFFFFFFFFFF FFFFFFFF
271 ** +OVER 7FEFFFFFFFFFFFFF 7F7FFFFF
272 ** -OVER FFEFFFFFFFFFFFFF FF7FFFFF
273 ** +UNDER 0010000000000000 00800000
274 ** -UNDER 8010000000000000 80800000
278 double64_be_read (unsigned char *cptr)
279 { int exponent, negative, upper, lower ;
282 negative = (cptr [0] & 0x80) ? 1 : 0 ;
283 exponent = ((cptr [0] & 0x7F) << 4) | ((cptr [1] >> 4) & 0xF) ;
285 /* Might not have a 64 bit long, so load the mantissa into a double. */
286 upper = (((cptr [1] & 0xF) << 24) | (cptr [2] << 16) | (cptr [3] << 8) | cptr [4]) ;
287 lower = (cptr [5] << 16) | (cptr [6] << 8) | cptr [7] ;
289 if (exponent == 0 && upper == 0 && lower == 0)
292 dvalue = upper + lower / ((double) 0x1000000) ;
293 dvalue += 0x10000000 ;
295 exponent = exponent - 0x3FF ;
297 dvalue = dvalue / ((double) 0x10000000) ;
303 dvalue *= (1 << exponent) ;
304 else if (exponent < 0)
305 dvalue /= (1 << abs (exponent)) ;
308 } /* double64_be_read */
311 double64_le_read (unsigned char *cptr)
312 { int exponent, negative, upper, lower ;
315 negative = (cptr [7] & 0x80) ? 1 : 0 ;
316 exponent = ((cptr [7] & 0x7F) << 4) | ((cptr [6] >> 4) & 0xF) ;
318 /* Might not have a 64 bit long, so load the mantissa into a double. */
319 upper = ((cptr [6] & 0xF) << 24) | (cptr [5] << 16) | (cptr [4] << 8) | cptr [3] ;
320 lower = (cptr [2] << 16) | (cptr [1] << 8) | cptr [0] ;
322 if (exponent == 0 && upper == 0 && lower == 0)
325 dvalue = upper + lower / ((double) 0x1000000) ;
326 dvalue += 0x10000000 ;
328 exponent = exponent - 0x3FF ;
330 dvalue = dvalue / ((double) 0x10000000) ;
336 dvalue *= (1 << exponent) ;
337 else if (exponent < 0)
338 dvalue /= (1 << abs (exponent)) ;
341 } /* double64_le_read */
344 double64_be_write (double in, unsigned char *out)
345 { int exponent, mantissa ;
347 memset (out, 0, sizeof (double)) ;
349 if (fabs (in) < 1e-30)
357 in = frexp (in, &exponent) ;
361 out [0] |= (exponent >> 4) & 0x7F ;
362 out [1] |= (exponent << 4) & 0xF0 ;
365 mantissa = lrint (floor (in)) ;
367 out [1] |= (mantissa >> 24) & 0xF ;
368 out [2] = (mantissa >> 16) & 0xFF ;
369 out [3] = (mantissa >> 8) & 0xFF ;
370 out [4] = mantissa & 0xFF ;
372 in = fmod (in, 1.0) ;
374 mantissa = lrint (floor (in)) ;
376 out [5] = (mantissa >> 16) & 0xFF ;
377 out [6] = (mantissa >> 8) & 0xFF ;
378 out [7] = mantissa & 0xFF ;
381 } /* double64_be_write */
384 double64_le_write (double in, unsigned char *out)
385 { int exponent, mantissa ;
387 memset (out, 0, sizeof (double)) ;
389 if (fabs (in) < 1e-30)
397 in = frexp (in, &exponent) ;
401 out [7] |= (exponent >> 4) & 0x7F ;
402 out [6] |= (exponent << 4) & 0xF0 ;
405 mantissa = lrint (floor (in)) ;
407 out [6] |= (mantissa >> 24) & 0xF ;
408 out [5] = (mantissa >> 16) & 0xFF ;
409 out [4] = (mantissa >> 8) & 0xFF ;
410 out [3] = mantissa & 0xFF ;
412 in = fmod (in, 1.0) ;
414 mantissa = lrint (floor (in)) ;
416 out [2] = (mantissa >> 16) & 0xFF ;
417 out [1] = (mantissa >> 8) & 0xFF ;
418 out [0] = mantissa & 0xFF ;
421 } /* double64_le_write */
423 /*==============================================================================================
424 ** Private functions.
428 double64_peak_update (SF_PRIVATE *psf, const double *buffer, int count, sf_count_t indx)
433 for (chan = 0 ; chan < psf->sf.channels ; chan++)
434 { fmaxval = fabs (buffer [chan]) ;
436 for (k = chan ; k < count ; k += psf->sf.channels)
437 if (fmaxval < fabs (buffer [k]))
438 { fmaxval = fabs (buffer [k]) ;
442 if (fmaxval > psf->peak_info->peaks [chan].value)
443 { psf->peak_info->peaks [chan].value = fmaxval ;
444 psf->peak_info->peaks [chan].position = psf->write_current + indx + (position / psf->sf.channels) ;
449 } /* double64_peak_update */
452 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.i [0] == 0x428c59fb && data.i [1] == 0x3ff3c0ca &&
464 data.c [0] == 0xfb && data.c [2] == 0x8c && data.c [4] == 0xca && data.c [6] == 0xf3)
465 return DOUBLE_CAN_RW_LE ;
467 /* If this test is true ints and floats are compatible and big endian. */
468 if ((data.i [0] == 0x3ff3c0ca && data.i [1] == 0x428c59fb) &&
469 (data.c [0] == 0x3f && data.c [2] == 0xc0 && data.c [4] == 0x42 && data.c [6] == 0x59))
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 d2i_array (const double *src, int count, int *dest, double scale)
491 { while (--count >= 0)
492 { dest [count] = lrint (scale * src [count]) ;
497 d2f_array (const double *src, int count, float *dest)
498 { while (--count >= 0)
499 { dest [count] = src [count] ;
504 s2d_array (const short *src, double *dest, int count)
505 { while (--count >= 0)
506 { dest [count] = src [count] ;
511 i2d_array (const int *src, double *dest, int count)
512 { while (--count >= 0)
513 { dest [count] = src [count] ;
518 f2d_array (const float *src, double *dest, int count)
519 { while (--count >= 0)
520 { dest [count] = src [count] ;
524 /*----------------------------------------------------------------------------------------------
528 host_read_d2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
529 { int bufferlen, readcount ;
530 sf_count_t total = 0 ;
533 bufferlen = ARRAY_LEN (psf->u.dbuf) ;
534 scale = (psf->float_int_mult == 0) ? 1.0 : 0x7FFF / psf->float_max ;
537 { if (len < bufferlen)
538 bufferlen = (int) len ;
539 readcount = psf_fread (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
541 if (psf->float_endswap == SF_TRUE)
542 endswap_double_array (psf->u.dbuf, readcount) ;
544 d2s_array (psf->u.dbuf, readcount, ptr + total, scale) ;
547 if (readcount < bufferlen)
552 } /* host_read_d2s */
555 host_read_d2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
556 { int bufferlen, readcount ;
557 sf_count_t total = 0 ;
559 bufferlen = ARRAY_LEN (psf->u.dbuf) ;
560 scale = (psf->float_int_mult == 0) ? 1.0 : 0x7FFFFFFF / psf->float_max ;
563 { if (len < bufferlen)
564 bufferlen = (int) len ;
565 readcount = psf_fread (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
567 if (psf->float_endswap == SF_TRUE)
568 endswap_double_array (psf->u.dbuf, bufferlen) ;
570 d2i_array (psf->u.dbuf, readcount, ptr + total, scale) ;
573 if (readcount < bufferlen)
578 } /* host_read_d2i */
581 host_read_d2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
582 { int bufferlen, readcount ;
583 sf_count_t total = 0 ;
585 bufferlen = ARRAY_LEN (psf->u.dbuf) ;
588 { if (len < bufferlen)
589 bufferlen = (int) len ;
590 readcount = psf_fread (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
592 if (psf->float_endswap == SF_TRUE)
593 endswap_double_array (psf->u.dbuf, bufferlen) ;
595 d2f_array (psf->u.dbuf, readcount, ptr + total) ;
598 if (readcount < bufferlen)
603 } /* host_read_d2f */
606 host_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
608 sf_count_t readcount, total = 0 ;
610 readcount = psf_fread (ptr, sizeof (double), len, psf) ;
612 if (psf->float_endswap != SF_TRUE)
615 /* If the read length was sensible, endswap output in one go. */
616 if (readcount < SENSIBLE_LEN)
617 { endswap_double_array (ptr, readcount) ;
621 bufferlen = SENSIBLE_LEN ;
623 { if (len < bufferlen)
624 bufferlen = (int) len ;
626 endswap_double_array (ptr + total, bufferlen) ;
636 host_write_s2d (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
637 { int bufferlen, writecount ;
638 sf_count_t total = 0 ;
640 bufferlen = ARRAY_LEN (psf->u.dbuf) ;
643 { if (len < bufferlen)
644 bufferlen = (int) len ;
646 s2d_array (ptr + total, psf->u.dbuf, bufferlen) ;
649 double64_peak_update (psf, psf->u.dbuf, bufferlen, total / psf->sf.channels) ;
651 if (psf->float_endswap == SF_TRUE)
652 endswap_double_array (psf->u.dbuf, bufferlen) ;
654 writecount = psf_fwrite (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
655 total += writecount ;
656 if (writecount < bufferlen)
662 } /* host_write_s2d */
665 host_write_i2d (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
666 { int bufferlen, writecount ;
667 sf_count_t total = 0 ;
669 bufferlen = ARRAY_LEN (psf->u.dbuf) ;
672 { if (len < bufferlen)
673 bufferlen = (int) len ;
674 i2d_array (ptr + total, psf->u.dbuf, bufferlen) ;
677 double64_peak_update (psf, psf->u.dbuf, bufferlen, total / psf->sf.channels) ;
679 if (psf->float_endswap == SF_TRUE)
680 endswap_double_array (psf->u.dbuf, bufferlen) ;
682 writecount = psf_fwrite (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
683 total += writecount ;
684 if (writecount < bufferlen)
690 } /* host_write_i2d */
693 host_write_f2d (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
694 { int bufferlen, writecount ;
695 sf_count_t total = 0 ;
697 bufferlen = ARRAY_LEN (psf->u.dbuf) ;
700 { if (len < bufferlen)
701 bufferlen = (int) len ;
702 f2d_array (ptr + total, psf->u.dbuf, bufferlen) ;
705 double64_peak_update (psf, psf->u.dbuf, bufferlen, total / psf->sf.channels) ;
707 if (psf->float_endswap == SF_TRUE)
708 endswap_double_array (psf->u.dbuf, bufferlen) ;
710 writecount = psf_fwrite (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
711 total += writecount ;
712 if (writecount < bufferlen)
718 } /* host_write_f2d */
721 host_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
722 { int bufferlen, writecount ;
723 sf_count_t total = 0 ;
726 double64_peak_update (psf, ptr, len, 0) ;
728 if (psf->float_endswap != SF_TRUE)
729 return psf_fwrite (ptr, sizeof (double), len, psf) ;
731 bufferlen = ARRAY_LEN (psf->u.dbuf) ;
734 { if (len < bufferlen)
735 bufferlen = (int) len ;
737 endswap_double_copy (psf->u.dbuf, ptr + total, bufferlen) ;
739 writecount = psf_fwrite (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
740 total += writecount ;
741 if (writecount < bufferlen)
749 /*=======================================================================================
753 replace_read_d2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
754 { int bufferlen, readcount ;
755 sf_count_t total = 0 ;
758 bufferlen = ARRAY_LEN (psf->u.dbuf) ;
759 scale = (psf->float_int_mult == 0) ? 1.0 : 0x7FFF / psf->float_max ;
762 { if (len < bufferlen)
763 bufferlen = (int) len ;
764 readcount = psf_fread (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
766 if (psf->float_endswap == SF_TRUE)
767 endswap_double_array (psf->u.dbuf, bufferlen) ;
769 d2bd_read (psf->u.dbuf, bufferlen) ;
771 d2s_array (psf->u.dbuf, readcount, ptr + total, scale) ;
773 if (readcount < bufferlen)
779 } /* replace_read_d2s */
782 replace_read_d2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
783 { int bufferlen, readcount ;
784 sf_count_t total = 0 ;
787 bufferlen = ARRAY_LEN (psf->u.dbuf) ;
788 scale = (psf->float_int_mult == 0) ? 1.0 : 0x7FFFFFFF / psf->float_max ;
791 { if (len < bufferlen)
792 bufferlen = (int) len ;
793 readcount = psf_fread (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
795 if (psf->float_endswap == SF_TRUE)
796 endswap_double_array (psf->u.dbuf, bufferlen) ;
798 d2bd_read (psf->u.dbuf, bufferlen) ;
800 d2i_array (psf->u.dbuf, readcount, ptr + total, scale) ;
802 if (readcount < bufferlen)
808 } /* replace_read_d2i */
811 replace_read_d2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
812 { int bufferlen, readcount ;
813 sf_count_t total = 0 ;
815 bufferlen = ARRAY_LEN (psf->u.dbuf) ;
818 { if (len < bufferlen)
819 bufferlen = (int) len ;
820 readcount = psf_fread (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
822 if (psf->float_endswap == SF_TRUE)
823 endswap_double_array (psf->u.dbuf, bufferlen) ;
825 d2bd_read (psf->u.dbuf, bufferlen) ;
827 memcpy (ptr + total, psf->u.dbuf, bufferlen * sizeof (double)) ;
830 if (readcount < bufferlen)
836 } /* replace_read_d2f */
839 replace_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
840 { int bufferlen, readcount ;
841 sf_count_t total = 0 ;
843 /* FIXME : This is probably nowhere near optimal. */
844 bufferlen = ARRAY_LEN (psf->u.dbuf) ;
847 { if (len < bufferlen)
848 bufferlen = (int) len ;
849 readcount = psf_fread (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
851 if (psf->float_endswap == SF_TRUE)
852 endswap_double_array (psf->u.dbuf, readcount) ;
854 d2bd_read (psf->u.dbuf, readcount) ;
856 memcpy (ptr + total, psf->u.dbuf, readcount * sizeof (double)) ;
859 if (readcount < bufferlen)
865 } /* replace_read_d */
868 replace_write_s2d (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
869 { int bufferlen, writecount ;
870 sf_count_t total = 0 ;
872 bufferlen = ARRAY_LEN (psf->u.dbuf) ;
875 { if (len < bufferlen)
876 bufferlen = (int) len ;
877 s2d_array (ptr + total, psf->u.dbuf, bufferlen) ;
880 double64_peak_update (psf, psf->u.dbuf, bufferlen, total / psf->sf.channels) ;
882 bd2d_write (psf->u.dbuf, bufferlen) ;
884 if (psf->float_endswap == SF_TRUE)
885 endswap_double_array (psf->u.dbuf, bufferlen) ;
887 writecount = psf_fwrite (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
888 total += writecount ;
889 if (writecount < bufferlen)
895 } /* replace_write_s2d */
898 replace_write_i2d (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
899 { int bufferlen, writecount ;
900 sf_count_t total = 0 ;
902 bufferlen = ARRAY_LEN (psf->u.dbuf) ;
905 { if (len < bufferlen)
906 bufferlen = (int) len ;
907 i2d_array (ptr + total, psf->u.dbuf, bufferlen) ;
910 double64_peak_update (psf, psf->u.dbuf, bufferlen, total / psf->sf.channels) ;
912 bd2d_write (psf->u.dbuf, bufferlen) ;
914 if (psf->float_endswap == SF_TRUE)
915 endswap_double_array (psf->u.dbuf, bufferlen) ;
917 writecount = psf_fwrite (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
918 total += writecount ;
919 if (writecount < bufferlen)
925 } /* replace_write_i2d */
928 replace_write_f2d (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
929 { int bufferlen, writecount ;
930 sf_count_t total = 0 ;
932 bufferlen = ARRAY_LEN (psf->u.dbuf) ;
935 { if (len < bufferlen)
936 bufferlen = (int) len ;
937 f2d_array (ptr + total, psf->u.dbuf, bufferlen) ;
939 bd2d_write (psf->u.dbuf, bufferlen) ;
941 if (psf->float_endswap == SF_TRUE)
942 endswap_double_array (psf->u.dbuf, bufferlen) ;
944 writecount = psf_fwrite (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
945 total += writecount ;
946 if (writecount < bufferlen)
952 } /* replace_write_f2d */
955 replace_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
956 { int bufferlen, writecount ;
957 sf_count_t total = 0 ;
959 /* FIXME : This is probably nowhere near optimal. */
961 double64_peak_update (psf, ptr, len, 0) ;
963 bufferlen = ARRAY_LEN (psf->u.dbuf) ;
966 { if (len < bufferlen)
967 bufferlen = (int) len ;
969 memcpy (psf->u.dbuf, ptr + total, bufferlen * sizeof (double)) ;
971 bd2d_write (psf->u.dbuf, bufferlen) ;
973 if (psf->float_endswap == SF_TRUE)
974 endswap_double_array (psf->u.dbuf, bufferlen) ;
976 writecount = psf_fwrite (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
977 total += writecount ;
978 if (writecount < bufferlen)
984 } /* replace_write_d */
986 /*----------------------------------------------------------------------------------------------
990 d2bd_read (double *buffer, int count)
991 { while (--count >= 0)
992 { buffer [count] = DOUBLE64_READ ((unsigned char *) (buffer + count)) ;
997 bd2d_write (double *buffer, int count)
998 { while (--count >= 0)
999 { DOUBLE64_WRITE (buffer [count], (unsigned char*) (buffer + count)) ;
1004 ** Do not edit or modify anything in this comment block.
1005 ** The arch-tag line is a file identity tag for the GNU Arch
1006 ** revision control system.
1008 ** arch-tag: 4ee243b7-8c7a-469b-869c-e9aa0ee3b77f