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