Git init
[external/libsndfile.git] / src / pcm.c
1 /*
2 ** Copyright (C) 1999-2009 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 <math.h>
22
23 #include        "sndfile.h"
24 #include        "sfendian.h"
25 #include        "common.h"
26
27 /* Need to be able to handle 3 byte (24 bit) integers. So defined a
28 ** type and use SIZEOF_TRIBYTE instead of (tribyte).
29 */
30
31 typedef void    tribyte ;
32
33 #define SIZEOF_TRIBYTE  3
34
35 static sf_count_t       pcm_read_sc2s   (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
36 static sf_count_t       pcm_read_uc2s   (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
37 static sf_count_t       pcm_read_bes2s  (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
38 static sf_count_t       pcm_read_les2s  (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
39 static sf_count_t       pcm_read_bet2s  (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
40 static sf_count_t       pcm_read_let2s  (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
41 static sf_count_t       pcm_read_bei2s  (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
42 static sf_count_t       pcm_read_lei2s  (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
43
44 static sf_count_t       pcm_read_sc2i   (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
45 static sf_count_t       pcm_read_uc2i   (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
46 static sf_count_t       pcm_read_bes2i  (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
47 static sf_count_t       pcm_read_les2i  (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
48 static sf_count_t       pcm_read_bet2i  (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
49 static sf_count_t       pcm_read_let2i  (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
50 static sf_count_t       pcm_read_bei2i  (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
51 static sf_count_t       pcm_read_lei2i  (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
52
53 static sf_count_t       pcm_read_sc2f   (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
54 static sf_count_t       pcm_read_uc2f   (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
55 static sf_count_t       pcm_read_bes2f  (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
56 static sf_count_t       pcm_read_les2f  (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
57 static sf_count_t       pcm_read_bet2f  (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
58 static sf_count_t       pcm_read_let2f  (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
59 static sf_count_t       pcm_read_bei2f  (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
60 static sf_count_t       pcm_read_lei2f  (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
61
62 static sf_count_t       pcm_read_sc2d   (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
63 static sf_count_t       pcm_read_uc2d   (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
64 static sf_count_t       pcm_read_bes2d  (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
65 static sf_count_t       pcm_read_les2d  (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
66 static sf_count_t       pcm_read_bet2d  (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
67 static sf_count_t       pcm_read_let2d  (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
68 static sf_count_t       pcm_read_bei2d  (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
69 static sf_count_t       pcm_read_lei2d  (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
70
71 static sf_count_t       pcm_write_s2sc  (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
72 static sf_count_t       pcm_write_s2uc  (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
73 static sf_count_t       pcm_write_s2bes (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
74 static sf_count_t       pcm_write_s2les (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
75 static sf_count_t       pcm_write_s2bet (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
76 static sf_count_t       pcm_write_s2let (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
77 static sf_count_t       pcm_write_s2bei (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
78 static sf_count_t       pcm_write_s2lei (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
79
80 static sf_count_t       pcm_write_i2sc  (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
81 static sf_count_t       pcm_write_i2uc  (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
82 static sf_count_t       pcm_write_i2bes (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
83 static sf_count_t       pcm_write_i2les (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
84 static sf_count_t       pcm_write_i2bet (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
85 static sf_count_t       pcm_write_i2let (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
86 static sf_count_t       pcm_write_i2bei (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
87 static sf_count_t       pcm_write_i2lei (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
88
89 static sf_count_t       pcm_write_f2sc  (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
90 static sf_count_t       pcm_write_f2uc  (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
91 static sf_count_t       pcm_write_f2bes (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
92 static sf_count_t       pcm_write_f2les (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
93 static sf_count_t       pcm_write_f2bet (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
94 static sf_count_t       pcm_write_f2let (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
95 static sf_count_t       pcm_write_f2bei (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
96 static sf_count_t       pcm_write_f2lei (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
97
98 static sf_count_t       pcm_write_d2sc  (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
99 static sf_count_t       pcm_write_d2uc  (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
100 static sf_count_t       pcm_write_d2bes (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
101 static sf_count_t       pcm_write_d2les (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
102 static sf_count_t       pcm_write_d2bet (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
103 static sf_count_t       pcm_write_d2let (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
104 static sf_count_t       pcm_write_d2bei (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
105 static sf_count_t       pcm_write_d2lei (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
106
107 /*-----------------------------------------------------------------------------------------------
108 */
109
110 enum
111 {       /* Char type for 8 bit files. */
112         SF_CHARS_SIGNED         = 200,
113         SF_CHARS_UNSIGNED       = 201
114 } ;
115
116 /*-----------------------------------------------------------------------------------------------
117 */
118
119 int
120 pcm_init (SF_PRIVATE *psf)
121 {       int chars = 0 ;
122
123         if (psf->bytewidth == 0 || psf->sf.channels == 0)
124         {       psf_log_printf (psf, "pcm_init : internal error : bytewitdh = %d, channels = %d\n", psf->bytewidth, psf->sf.channels) ;
125                 return SFE_INTERNAL ;
126                 } ;
127
128         psf->blockwidth = psf->bytewidth * psf->sf.channels ;
129
130         if ((SF_CODEC (psf->sf.format)) == SF_FORMAT_PCM_S8)
131                 chars = SF_CHARS_SIGNED ;
132         else if ((SF_CODEC (psf->sf.format)) == SF_FORMAT_PCM_U8)
133                 chars = SF_CHARS_UNSIGNED ;
134
135         if (CPU_IS_BIG_ENDIAN)
136                 psf->data_endswap = (psf->endian == SF_ENDIAN_BIG) ? SF_FALSE : SF_TRUE ;
137         else
138                 psf->data_endswap = (psf->endian == SF_ENDIAN_LITTLE) ? SF_FALSE : SF_TRUE ;
139
140         if (psf->file.mode == SFM_READ || psf->file.mode == SFM_RDWR)
141         {       switch (psf->bytewidth * 0x10000 + psf->endian + chars)
142                 {       case (0x10000 + SF_ENDIAN_BIG + SF_CHARS_SIGNED) :
143                         case (0x10000 + SF_ENDIAN_LITTLE + SF_CHARS_SIGNED) :
144                                         psf->read_short         = pcm_read_sc2s ;
145                                         psf->read_int           = pcm_read_sc2i ;
146                                         psf->read_float         = pcm_read_sc2f ;
147                                         psf->read_double        = pcm_read_sc2d ;
148                                         break ;
149                         case (0x10000 + SF_ENDIAN_BIG + SF_CHARS_UNSIGNED) :
150                         case (0x10000 + SF_ENDIAN_LITTLE + SF_CHARS_UNSIGNED) :
151                                         psf->read_short         = pcm_read_uc2s ;
152                                         psf->read_int           = pcm_read_uc2i ;
153                                         psf->read_float         = pcm_read_uc2f ;
154                                         psf->read_double        = pcm_read_uc2d ;
155                                         break ;
156
157                         case (2 * 0x10000 + SF_ENDIAN_BIG) :
158                                         psf->read_short         = pcm_read_bes2s ;
159                                         psf->read_int           = pcm_read_bes2i ;
160                                         psf->read_float         = pcm_read_bes2f ;
161                                         psf->read_double        = pcm_read_bes2d ;
162                                         break ;
163                         case (3 * 0x10000 + SF_ENDIAN_BIG) :
164                                         psf->read_short         = pcm_read_bet2s ;
165                                         psf->read_int           = pcm_read_bet2i ;
166                                         psf->read_float         = pcm_read_bet2f ;
167                                         psf->read_double        = pcm_read_bet2d ;
168                                         break ;
169                         case (4 * 0x10000 + SF_ENDIAN_BIG) :
170
171                                         psf->read_short         = pcm_read_bei2s ;
172                                         psf->read_int           = pcm_read_bei2i ;
173                                         psf->read_float         = pcm_read_bei2f ;
174                                         psf->read_double        = pcm_read_bei2d ;
175                                         break ;
176
177                         case (2 * 0x10000 + SF_ENDIAN_LITTLE) :
178                                         psf->read_short         = pcm_read_les2s ;
179                                         psf->read_int           = pcm_read_les2i ;
180                                         psf->read_float         = pcm_read_les2f ;
181                                         psf->read_double        = pcm_read_les2d ;
182                                         break ;
183                         case (3 * 0x10000 + SF_ENDIAN_LITTLE) :
184                                         psf->read_short         = pcm_read_let2s ;
185                                         psf->read_int           = pcm_read_let2i ;
186                                         psf->read_float         = pcm_read_let2f ;
187                                         psf->read_double        = pcm_read_let2d ;
188                                         break ;
189                         case (4 * 0x10000 + SF_ENDIAN_LITTLE) :
190                                         psf->read_short         = pcm_read_lei2s ;
191                                         psf->read_int           = pcm_read_lei2i ;
192                                         psf->read_float         = pcm_read_lei2f ;
193                                         psf->read_double        = pcm_read_lei2d ;
194                                         break ;
195                         default :
196                                 psf_log_printf (psf, "pcm.c returning SFE_UNIMPLEMENTED\nbytewidth %d    endian %d\n", psf->bytewidth, psf->endian) ;
197                                 return SFE_UNIMPLEMENTED ;
198                         } ;
199                 } ;
200
201         if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
202         {       switch (psf->bytewidth * 0x10000 + psf->endian + chars)
203                 {       case (0x10000 + SF_ENDIAN_BIG + SF_CHARS_SIGNED) :
204                         case (0x10000 + SF_ENDIAN_LITTLE + SF_CHARS_SIGNED) :
205                                         psf->write_short        = pcm_write_s2sc ;
206                                         psf->write_int          = pcm_write_i2sc ;
207                                         psf->write_float        = pcm_write_f2sc ;
208                                         psf->write_double       = pcm_write_d2sc ;
209                                         break ;
210                         case (0x10000 + SF_ENDIAN_BIG + SF_CHARS_UNSIGNED) :
211                         case (0x10000 + SF_ENDIAN_LITTLE + SF_CHARS_UNSIGNED) :
212                                         psf->write_short        = pcm_write_s2uc ;
213                                         psf->write_int          = pcm_write_i2uc ;
214                                         psf->write_float        = pcm_write_f2uc ;
215                                         psf->write_double       = pcm_write_d2uc ;
216                                         break ;
217
218                         case (2 * 0x10000 + SF_ENDIAN_BIG) :
219                                         psf->write_short        = pcm_write_s2bes ;
220                                         psf->write_int          = pcm_write_i2bes ;
221                                         psf->write_float        = pcm_write_f2bes ;
222                                         psf->write_double       = pcm_write_d2bes ;
223                                         break ;
224
225                         case (3 * 0x10000 + SF_ENDIAN_BIG) :
226                                         psf->write_short        = pcm_write_s2bet ;
227                                         psf->write_int          = pcm_write_i2bet ;
228                                         psf->write_float        = pcm_write_f2bet ;
229                                         psf->write_double       = pcm_write_d2bet ;
230                                         break ;
231
232                         case (4 * 0x10000 + SF_ENDIAN_BIG) :
233                                         psf->write_short        = pcm_write_s2bei ;
234                                         psf->write_int          = pcm_write_i2bei ;
235                                         psf->write_float        = pcm_write_f2bei ;
236                                         psf->write_double       = pcm_write_d2bei ;
237                                         break ;
238
239                         case (2 * 0x10000 + SF_ENDIAN_LITTLE) :
240                                         psf->write_short        = pcm_write_s2les ;
241                                         psf->write_int          = pcm_write_i2les ;
242                                         psf->write_float        = pcm_write_f2les ;
243                                         psf->write_double       = pcm_write_d2les ;
244                                         break ;
245
246                         case (3 * 0x10000 + SF_ENDIAN_LITTLE) :
247                                         psf->write_short        = pcm_write_s2let ;
248                                         psf->write_int          = pcm_write_i2let ;
249                                         psf->write_float        = pcm_write_f2let ;
250                                         psf->write_double       = pcm_write_d2let ;
251                                         break ;
252
253                         case (4 * 0x10000 + SF_ENDIAN_LITTLE) :
254                                         psf->write_short        = pcm_write_s2lei ;
255                                         psf->write_int          = pcm_write_i2lei ;
256                                         psf->write_float        = pcm_write_f2lei ;
257                                         psf->write_double       = pcm_write_d2lei ;
258                                         break ;
259
260                         default :
261                                 psf_log_printf (psf, "pcm.c returning SFE_UNIMPLEMENTED\nbytewidth %s    endian %d\n", psf->bytewidth, psf->endian) ;
262                                 return SFE_UNIMPLEMENTED ;
263                         } ;
264
265                 } ;
266
267         if (psf->filelength > psf->dataoffset)
268         {       psf->datalength = (psf->dataend > 0) ? psf->dataend - psf->dataoffset :
269                                                         psf->filelength - psf->dataoffset ;
270                 }
271         else
272                 psf->datalength = 0 ;
273
274         psf->sf.frames = psf->blockwidth > 0 ? psf->datalength / psf->blockwidth : 0 ;
275
276         return 0 ;
277 } /* pcm_init */
278
279 /*==============================================================================
280 */
281
282 static inline void
283 sc2s_array      (signed char *src, int count, short *dest)
284 {       while (--count >= 0)
285         {       dest [count] = src [count] << 8 ;
286                 } ;
287 } /* sc2s_array */
288
289 static inline void
290 uc2s_array      (unsigned char *src, int count, short *dest)
291 {       while (--count >= 0)
292         {       dest [count] = (((short) src [count]) - 0x80) << 8 ;
293                 } ;
294 } /* uc2s_array */
295
296 static inline void
297 let2s_array (tribyte *src, int count, short *dest)
298 {       unsigned char   *ucptr ;
299
300         ucptr = ((unsigned char*) src) + 3 * count ;
301         while (--count >= 0)
302         {       ucptr -= 3 ;
303                 dest [count] = LET2H_SHORT_PTR (ucptr) ;
304                 } ;
305 } /* let2s_array */
306
307 static inline void
308 bet2s_array (tribyte *src, int count, short *dest)
309 {       unsigned char   *ucptr ;
310
311         ucptr = ((unsigned char*) src) + 3 * count ;
312         while (--count >= 0)
313         {       ucptr -= 3 ;
314                 dest [count] = BET2H_SHORT_PTR (ucptr) ;
315                         } ;
316 } /* bet2s_array */
317
318 static inline void
319 lei2s_array (int *src, int count, short *dest)
320 {       int value ;
321
322         while (--count >= 0)
323         {       value = LEI2H_INT (src [count]) ;
324                 dest [count] = value >> 16 ;
325                 } ;
326 } /* lei2s_array */
327
328 static inline void
329 bei2s_array (int *src, int count, short *dest)
330 {       int value ;
331
332         while (--count >= 0)
333         {       value = BEI2H_INT (src [count]) ;
334                 dest [count] = value >> 16 ;
335                 } ;
336 } /* bei2s_array */
337
338 /*--------------------------------------------------------------------------
339 */
340
341 static inline void
342 sc2i_array      (signed char *src, int count, int *dest)
343 {       while (--count >= 0)
344         {       dest [count] = ((int) src [count]) << 24 ;
345                 } ;
346 } /* sc2i_array */
347
348 static inline void
349 uc2i_array      (unsigned char *src, int count, int *dest)
350 {       while (--count >= 0)
351         {       dest [count] = (((int) src [count]) - 128) << 24 ;
352                 } ;
353 } /* uc2i_array */
354
355 static inline void
356 bes2i_array (short *src, int count, int *dest)
357 {       short value ;
358
359         while (--count >= 0)
360         {       value = BES2H_SHORT (src [count]) ;
361                 dest [count] = value << 16 ;
362                 } ;
363 } /* bes2i_array */
364
365 static inline void
366 les2i_array (short *src, int count, int *dest)
367 {       short value ;
368
369         while (--count >= 0)
370         {       value = LES2H_SHORT (src [count]) ;
371                 dest [count] = value << 16 ;
372                 } ;
373 } /* les2i_array */
374
375 static inline void
376 bet2i_array (tribyte *src, int count, int *dest)
377 {       unsigned char   *ucptr ;
378
379         ucptr = ((unsigned char*) src) + 3 * count ;
380         while (--count >= 0)
381         {       ucptr -= 3 ;
382                 dest [count] = BET2H_INT_PTR (ucptr) ;
383                         } ;
384 } /* bet2i_array */
385
386 static inline void
387 let2i_array (tribyte *src, int count, int *dest)
388 {       unsigned char   *ucptr ;
389
390         ucptr = ((unsigned char*) src) + 3 * count ;
391         while (--count >= 0)
392         {       ucptr -= 3 ;
393                 dest [count] = LET2H_INT_PTR (ucptr) ;
394                 } ;
395 } /* let2i_array */
396
397 /*--------------------------------------------------------------------------
398 */
399
400 static inline void
401 sc2f_array      (signed char *src, int count, float *dest, float normfact)
402 {       while (--count >= 0)
403                 dest [count] = ((float) src [count]) * normfact ;
404 } /* sc2f_array */
405
406 static inline void
407 uc2f_array      (unsigned char *src, int count, float *dest, float normfact)
408 {       while (--count >= 0)
409                 dest [count] = (((int) src [count]) - 128) * normfact ;
410 } /* uc2f_array */
411
412 static inline void
413 les2f_array (short *src, int count, float *dest, float normfact)
414 {       short   value ;
415
416         while (--count >= 0)
417         {       value = src [count] ;
418                 value = LES2H_SHORT (value) ;
419                 dest [count] = ((float) value) * normfact ;
420                 } ;
421 } /* les2f_array */
422
423 static inline void
424 bes2f_array (short *src, int count, float *dest, float normfact)
425 {       short                   value ;
426
427         while (--count >= 0)
428         {       value = src [count] ;
429                 value = BES2H_SHORT (value) ;
430                 dest [count] = ((float) value) * normfact ;
431                 } ;
432 } /* bes2f_array */
433
434 static inline void
435 let2f_array (tribyte *src, int count, float *dest, float normfact)
436 {       unsigned char   *ucptr ;
437         int                     value ;
438
439         ucptr = ((unsigned char*) src) + 3 * count ;
440         while (--count >= 0)
441         {       ucptr -= 3 ;
442                 value = LET2H_INT_PTR (ucptr) ;
443                 dest [count] = ((float) value) * normfact ;
444                 } ;
445 } /* let2f_array */
446
447 static inline void
448 bet2f_array (tribyte *src, int count, float *dest, float normfact)
449 {       unsigned char   *ucptr ;
450         int                             value ;
451
452         ucptr = ((unsigned char*) src) + 3 * count ;
453         while (--count >= 0)
454         {       ucptr -= 3 ;
455                 value = BET2H_INT_PTR (ucptr) ;
456                 dest [count] = ((float) value) * normfact ;
457                         } ;
458 } /* bet2f_array */
459
460 static inline void
461 lei2f_array (int *src, int count, float *dest, float normfact)
462 {       int                     value ;
463
464         while (--count >= 0)
465         {       value = src [count] ;
466                 value = LEI2H_INT (value) ;
467                 dest [count] = ((float) value) * normfact ;
468                 } ;
469 } /* lei2f_array */
470
471 static inline void
472 bei2f_array (int *src, int count, float *dest, float normfact)
473 {       int                     value ;
474
475         while (--count >= 0)
476         {       value = src [count] ;
477                 value = BEI2H_INT (value) ;
478                 dest [count] = ((float) value) * normfact ;
479                 } ;
480 } /* bei2f_array */
481
482 /*--------------------------------------------------------------------------
483 */
484
485 static inline void
486 sc2d_array      (signed char *src, int count, double *dest, double normfact)
487 {       while (--count >= 0)
488                 dest [count] = ((double) src [count]) * normfact ;
489 } /* sc2d_array */
490
491 static inline void
492 uc2d_array      (unsigned char *src, int count, double *dest, double normfact)
493 {       while (--count >= 0)
494                 dest [count] = (((int) src [count]) - 128) * normfact ;
495 } /* uc2d_array */
496
497 static inline void
498 les2d_array (short *src, int count, double *dest, double normfact)
499 {       short   value ;
500
501         while (--count >= 0)
502         {       value = src [count] ;
503                 value = LES2H_SHORT (value) ;
504                 dest [count] = ((double) value) * normfact ;
505                 } ;
506 } /* les2d_array */
507
508 static inline void
509 bes2d_array (short *src, int count, double *dest, double normfact)
510 {       short   value ;
511
512         while (--count >= 0)
513         {       value = src [count] ;
514                 value = BES2H_SHORT (value) ;
515                 dest [count] = ((double) value) * normfact ;
516                 } ;
517 } /* bes2d_array */
518
519 static inline void
520 let2d_array (tribyte *src, int count, double *dest, double normfact)
521 {       unsigned char   *ucptr ;
522         int                             value ;
523
524         ucptr = ((unsigned char*) src) + 3 * count ;
525         while (--count >= 0)
526         {       ucptr -= 3 ;
527                 value = LET2H_INT_PTR (ucptr) ;
528                 dest [count] = ((double) value) * normfact ;
529                 } ;
530 } /* let2d_array */
531
532 static inline void
533 bet2d_array (tribyte *src, int count, double *dest, double normfact)
534 {       unsigned char   *ucptr ;
535         int                             value ;
536
537         ucptr = ((unsigned char*) src) + 3 * count ;
538         while (--count >= 0)
539         {       ucptr -= 3 ;
540                 value = (ucptr [0] << 24) | (ucptr [1] << 16) | (ucptr [2] << 8) ;
541                 dest [count] = ((double) value) * normfact ;
542                 } ;
543 } /* bet2d_array */
544
545 static inline void
546 lei2d_array (int *src, int count, double *dest, double normfact)
547 {       int     value ;
548
549         while (--count >= 0)
550         {       value = src [count] ;
551                 value = LEI2H_INT (value) ;
552                 dest [count] = ((double) value) * normfact ;
553                 } ;
554 } /* lei2d_array */
555
556 static inline void
557 bei2d_array (int *src, int count, double *dest, double normfact)
558 {       int     value ;
559
560         while (--count >= 0)
561         {       value = src [count] ;
562                 value = BEI2H_INT (value) ;
563                 dest [count] = ((double) value) * normfact ;
564                 } ;
565 } /* bei2d_array */
566
567 /*--------------------------------------------------------------------------
568 */
569
570 static inline void
571 s2sc_array      (const short *src, signed char *dest, int count)
572 {       while (--count >= 0)
573                 dest [count] = src [count] >> 8 ;
574 } /* s2sc_array */
575
576 static inline void
577 s2uc_array      (const short *src, unsigned char *dest, int count)
578 {       while (--count >= 0)
579                 dest [count] = (src [count] >> 8) + 0x80 ;
580 } /* s2uc_array */
581
582 static inline void
583 s2let_array (const short *src, tribyte *dest, int count)
584 {       unsigned char   *ucptr ;
585
586         ucptr = ((unsigned char*) dest) + 3 * count ;
587         while (--count >= 0)
588         {       ucptr -= 3 ;
589                 ucptr [0] = 0 ;
590                 ucptr [1] = src [count] ;
591                 ucptr [2] = src [count] >> 8 ;
592                 } ;
593 } /* s2let_array */
594
595 static inline void
596 s2bet_array (const short *src, tribyte *dest, int count)
597 {       unsigned char   *ucptr ;
598
599         ucptr = ((unsigned char*) dest) + 3 * count ;
600         while (--count >= 0)
601         {       ucptr -= 3 ;
602                 ucptr [2] = 0 ;
603                 ucptr [1] = src [count] ;
604                 ucptr [0] = src [count] >> 8 ;
605                 } ;
606 } /* s2bet_array */
607
608 static inline void
609 s2lei_array (const short *src, int *dest, int count)
610 {       unsigned char   *ucptr ;
611
612         ucptr = ((unsigned char*) dest) + 4 * count ;
613         while (--count >= 0)
614         {       ucptr -= 4 ;
615                 ucptr [0] = 0 ;
616                 ucptr [1] = 0 ;
617                 ucptr [2] = src [count] ;
618                 ucptr [3] = src [count] >> 8 ;
619                 } ;
620 } /* s2lei_array */
621
622 static inline void
623 s2bei_array (const short *src, int *dest, int count)
624 {       unsigned char   *ucptr ;
625
626         ucptr = ((unsigned char*) dest) + 4 * count ;
627         while (--count >= 0)
628         {       ucptr -= 4 ;
629                 ucptr [0] = src [count] >> 8 ;
630                 ucptr [1] = src [count] ;
631                 ucptr [2] = 0 ;
632                 ucptr [3] = 0 ;
633                 } ;
634 } /* s2bei_array */
635
636 /*--------------------------------------------------------------------------
637 */
638
639 static inline void
640 i2sc_array      (const int *src, signed char *dest, int count)
641 {       while (--count >= 0)
642                 dest [count] = (src [count] >> 24) ;
643 } /* i2sc_array */
644
645 static inline void
646 i2uc_array      (const int *src, unsigned char *dest, int count)
647 {       while (--count >= 0)
648                 dest [count] = ((src [count] >> 24) + 128) ;
649 } /* i2uc_array */
650
651 static inline void
652 i2bes_array (const int *src, short *dest, int count)
653 {       unsigned char   *ucptr ;
654
655         ucptr = ((unsigned char*) dest) + 2 * count ;
656         while (--count >= 0)
657         {       ucptr -= 2 ;
658                 ucptr [0] = src [count] >> 24 ;
659                 ucptr [1] = src [count] >> 16 ;
660                 } ;
661 } /* i2bes_array */
662
663 static inline void
664 i2les_array (const int *src, short *dest, int count)
665 {       unsigned char   *ucptr ;
666
667         ucptr = ((unsigned char*) dest) + 2 * count ;
668         while (--count >= 0)
669         {       ucptr -= 2 ;
670                 ucptr [0] = src [count] >> 16 ;
671                 ucptr [1] = src [count] >> 24 ;
672                 } ;
673 } /* i2les_array */
674
675 static inline void
676 i2let_array (const int *src, tribyte *dest, int count)
677 {       unsigned char   *ucptr ;
678         int                             value ;
679
680         ucptr = ((unsigned char*) dest) + 3 * count ;
681         while (--count >= 0)
682         {       ucptr -= 3 ;
683                 value = src [count] >> 8 ;
684                 ucptr [0] = value ;
685                 ucptr [1] = value >> 8 ;
686                 ucptr [2] = value >> 16 ;
687                 } ;
688 } /* i2let_array */
689
690 static inline void
691 i2bet_array (const int *src, tribyte *dest, int count)
692 {       unsigned char   *ucptr ;
693         int                             value ;
694
695         ucptr = ((unsigned char*) dest) + 3 * count ;
696         while (--count >= 0)
697         {       ucptr -= 3 ;
698                 value = src [count] >> 8 ;
699                 ucptr [2] = value ;
700                 ucptr [1] = value >> 8 ;
701                 ucptr [0] = value >> 16 ;
702                 } ;
703 } /* i2bet_array */
704
705 /*===============================================================================================
706 */
707
708 static sf_count_t
709 pcm_read_sc2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
710 {       int                     bufferlen, readcount ;
711         sf_count_t      total = 0 ;
712
713         bufferlen = ARRAY_LEN (psf->u.scbuf) ;
714
715         while (len > 0)
716         {       if (len < bufferlen)
717                         bufferlen = (int) len ;
718                 readcount = psf_fread (psf->u.scbuf, sizeof (signed char), bufferlen, psf) ;
719                 sc2s_array (psf->u.scbuf, readcount, ptr + total) ;
720                 total += readcount ;
721                 if (readcount < bufferlen)
722                         break ;
723                 len -= readcount ;
724                 } ;
725
726         return total ;
727 } /* pcm_read_sc2s */
728
729 static sf_count_t
730 pcm_read_uc2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
731 {       int                     bufferlen, readcount ;
732         sf_count_t      total = 0 ;
733
734         bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
735
736         while (len > 0)
737         {       if (len < bufferlen)
738                         bufferlen = (int) len ;
739                 readcount = psf_fread (psf->u.ucbuf, sizeof (unsigned char), bufferlen, psf) ;
740                 uc2s_array (psf->u.ucbuf, readcount, ptr + total) ;
741                 total += readcount ;
742                 if (readcount < bufferlen)
743                         break ;
744                 len -= readcount ;
745                 } ;
746
747         return total ;
748 } /* pcm_read_uc2s */
749
750 static sf_count_t
751 pcm_read_bes2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
752 {       int             total ;
753
754         total = psf_fread (ptr, sizeof (short), len, psf) ;
755         if (CPU_IS_LITTLE_ENDIAN)
756                 endswap_short_array (ptr, len) ;
757
758         return total ;
759 } /* pcm_read_bes2s */
760
761 static sf_count_t
762 pcm_read_les2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
763 {       int             total ;
764
765         total = psf_fread (ptr, sizeof (short), len, psf) ;
766         if (CPU_IS_BIG_ENDIAN)
767                 endswap_short_array (ptr, len) ;
768
769         return total ;
770 } /* pcm_read_les2s */
771
772 static sf_count_t
773 pcm_read_bet2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
774 {       int                     bufferlen, readcount ;
775         sf_count_t      total = 0 ;
776
777         bufferlen = sizeof (psf->u.ucbuf) / SIZEOF_TRIBYTE ;
778
779         while (len > 0)
780         {       if (len < bufferlen)
781                         bufferlen = (int) len ;
782                 readcount = psf_fread (psf->u.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
783                 bet2s_array ((tribyte*) (psf->u.ucbuf), readcount, ptr + total) ;
784                 total += readcount ;
785                 if (readcount < bufferlen)
786                         break ;
787                 len -= readcount ;
788                 } ;
789
790         return total ;
791 } /* pcm_read_bet2s */
792
793 static sf_count_t
794 pcm_read_let2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
795 {       int                     bufferlen, readcount ;
796         sf_count_t      total = 0 ;
797
798         bufferlen = sizeof (psf->u.ucbuf) / SIZEOF_TRIBYTE ;
799
800         while (len > 0)
801         {       if (len < bufferlen)
802                         bufferlen = (int) len ;
803                 readcount = psf_fread (psf->u.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
804                 let2s_array ((tribyte*) (psf->u.ucbuf), readcount, ptr + total) ;
805                 total += readcount ;
806                 if (readcount < bufferlen)
807                         break ;
808                 len -= readcount ;
809                 } ;
810
811         return total ;
812 } /* pcm_read_let2s */
813
814 static sf_count_t
815 pcm_read_bei2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
816 {       int                     bufferlen, readcount ;
817         sf_count_t      total = 0 ;
818
819         bufferlen = ARRAY_LEN (psf->u.ibuf) ;
820
821         while (len > 0)
822         {       if (len < bufferlen)
823                         bufferlen = (int) len ;
824                 readcount = psf_fread (psf->u.ibuf, sizeof (int), bufferlen, psf) ;
825                 bei2s_array (psf->u.ibuf, readcount, ptr + total) ;
826                 total += readcount ;
827                 if (readcount < bufferlen)
828                         break ;
829                 len -= readcount ;
830                 } ;
831
832         return total ;
833 } /* pcm_read_bei2s */
834
835 static sf_count_t
836 pcm_read_lei2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
837 {       int                     bufferlen, readcount ;
838         sf_count_t      total = 0 ;
839
840         bufferlen = ARRAY_LEN (psf->u.ibuf) ;
841
842         while (len > 0)
843         {       if (len < bufferlen)
844                         bufferlen = (int) len ;
845                 readcount = psf_fread (psf->u.ibuf, sizeof (int), bufferlen, psf) ;
846                 lei2s_array (psf->u.ibuf, readcount, ptr + total) ;
847                 total += readcount ;
848                 if (readcount < bufferlen)
849                         break ;
850                 len -= readcount ;
851                 } ;
852
853         return total ;
854 } /* pcm_read_lei2s */
855
856 /*-----------------------------------------------------------------------------------------------
857 */
858
859 static sf_count_t
860 pcm_read_sc2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
861 {       int                     bufferlen, readcount ;
862         sf_count_t      total = 0 ;
863
864         bufferlen = ARRAY_LEN (psf->u.scbuf) ;
865
866         while (len > 0)
867         {       if (len < bufferlen)
868                         bufferlen = (int) len ;
869                 readcount = psf_fread (psf->u.scbuf, sizeof (signed char), bufferlen, psf) ;
870                 sc2i_array (psf->u.scbuf, readcount, ptr + total) ;
871                 total += readcount ;
872                 if (readcount < bufferlen)
873                         break ;
874                 len -= readcount ;
875                 } ;
876
877         return total ;
878 } /* pcm_read_sc2i */
879
880 static sf_count_t
881 pcm_read_uc2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
882 {       int                     bufferlen, readcount ;
883         sf_count_t      total = 0 ;
884
885         bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
886
887         while (len > 0)
888         {       if (len < bufferlen)
889                         bufferlen = (int) len ;
890                 readcount = psf_fread (psf->u.ucbuf, sizeof (unsigned char), bufferlen, psf) ;
891                 uc2i_array (psf->u.ucbuf, readcount, ptr + total) ;
892                 total += readcount ;
893                 if (readcount < bufferlen)
894                         break ;
895                 len -= readcount ;
896                 } ;
897
898         return total ;
899 } /* pcm_read_uc2i */
900
901 static sf_count_t
902 pcm_read_bes2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
903 {       int                     bufferlen, readcount ;
904         sf_count_t      total = 0 ;
905
906         bufferlen = ARRAY_LEN (psf->u.sbuf) ;
907
908         while (len > 0)
909         {       if (len < bufferlen)
910                         bufferlen = (int) len ;
911                 readcount = psf_fread (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
912                 bes2i_array (psf->u.sbuf, readcount, ptr + total) ;
913                 total += readcount ;
914                 if (readcount < bufferlen)
915                         break ;
916                 len -= readcount ;
917                 } ;
918
919         return total ;
920 } /* pcm_read_bes2i */
921
922 static sf_count_t
923 pcm_read_les2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
924 {       int                     bufferlen, readcount ;
925         sf_count_t      total = 0 ;
926
927         bufferlen = ARRAY_LEN (psf->u.sbuf) ;
928
929         while (len > 0)
930         {       if (len < bufferlen)
931                         bufferlen = (int) len ;
932                 readcount = psf_fread (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
933                 les2i_array (psf->u.sbuf, readcount, ptr + total) ;
934                 total += readcount ;
935                 if (readcount < bufferlen)
936                         break ;
937                 len -= readcount ;
938                 } ;
939
940         return total ;
941 } /* pcm_read_les2i */
942
943 static sf_count_t
944 pcm_read_bet2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
945 {       int                     bufferlen, readcount ;
946         sf_count_t      total = 0 ;
947
948         bufferlen = sizeof (psf->u.ucbuf) / SIZEOF_TRIBYTE ;
949
950         while (len > 0)
951         {       if (len < bufferlen)
952                         bufferlen = (int) len ;
953                 readcount = psf_fread (psf->u.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
954                 bet2i_array ((tribyte*) (psf->u.ucbuf), readcount, ptr + total) ;
955                 total += readcount ;
956                 if (readcount < bufferlen)
957                         break ;
958                 len -= readcount ;
959                 } ;
960
961         return total ;
962 } /* pcm_read_bet2i */
963
964 static sf_count_t
965 pcm_read_let2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
966 {       int                     bufferlen, readcount ;
967         sf_count_t      total = 0 ;
968
969         bufferlen = sizeof (psf->u.ucbuf) / SIZEOF_TRIBYTE ;
970
971         while (len > 0)
972         {       if (len < bufferlen)
973                         bufferlen = (int) len ;
974                 readcount = psf_fread (psf->u.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
975                 let2i_array ((tribyte*) (psf->u.ucbuf), readcount, ptr + total) ;
976                 total += readcount ;
977                 if (readcount < bufferlen)
978                         break ;
979                 len -= readcount ;
980                 } ;
981
982         return total ;
983 } /* pcm_read_let2i */
984
985 static sf_count_t
986 pcm_read_bei2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
987 {       int             total ;
988
989         total = psf_fread (ptr, sizeof (int), len, psf) ;
990         if (CPU_IS_LITTLE_ENDIAN)
991                 endswap_int_array       (ptr, len) ;
992
993         return total ;
994 } /* pcm_read_bei2i */
995
996 static sf_count_t
997 pcm_read_lei2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
998 {       int             total ;
999
1000         total = psf_fread (ptr, sizeof (int), len, psf) ;
1001         if (CPU_IS_BIG_ENDIAN)
1002                 endswap_int_array       (ptr, len) ;
1003
1004         return total ;
1005 } /* pcm_read_lei2i */
1006
1007 /*-----------------------------------------------------------------------------------------------
1008 */
1009
1010 static sf_count_t
1011 pcm_read_sc2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
1012 {       int                     bufferlen, readcount ;
1013         sf_count_t      total = 0 ;
1014         float   normfact ;
1015
1016         normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x80) : 1.0 ;
1017
1018         bufferlen = ARRAY_LEN (psf->u.scbuf) ;
1019
1020         while (len > 0)
1021         {       if (len < bufferlen)
1022                         bufferlen = (int) len ;
1023                 readcount = psf_fread (psf->u.scbuf, sizeof (signed char), bufferlen, psf) ;
1024                 sc2f_array (psf->u.scbuf, readcount, ptr + total, normfact) ;
1025                 total += readcount ;
1026                 if (readcount < bufferlen)
1027                         break ;
1028                 len -= readcount ;
1029                 } ;
1030
1031         return total ;
1032 } /* pcm_read_sc2f */
1033
1034 static sf_count_t
1035 pcm_read_uc2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
1036 {       int                     bufferlen, readcount ;
1037         sf_count_t      total = 0 ;
1038         float   normfact ;
1039
1040         normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x80) : 1.0 ;
1041
1042         bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
1043
1044         while (len > 0)
1045         {       if (len < bufferlen)
1046                         bufferlen = (int) len ;
1047                 readcount = psf_fread (psf->u.ucbuf, sizeof (unsigned char), bufferlen, psf) ;
1048                 uc2f_array (psf->u.ucbuf, readcount, ptr + total, normfact) ;
1049                 total += readcount ;
1050                 if (readcount < bufferlen)
1051                         break ;
1052                 len -= readcount ;
1053                 } ;
1054
1055         return total ;
1056 } /* pcm_read_uc2f */
1057
1058 static sf_count_t
1059 pcm_read_bes2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
1060 {       int                     bufferlen, readcount ;
1061         sf_count_t      total = 0 ;
1062         float   normfact ;
1063
1064         normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x8000) : 1.0 ;
1065
1066         bufferlen = ARRAY_LEN (psf->u.sbuf) ;
1067
1068         while (len > 0)
1069         {       if (len < bufferlen)
1070                         bufferlen = (int) len ;
1071                 readcount = psf_fread (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
1072                 bes2f_array (psf->u.sbuf, readcount, ptr + total, normfact) ;
1073                 total += readcount ;
1074                 if (readcount < bufferlen)
1075                         break ;
1076                 len -= readcount ;
1077                 } ;
1078
1079         return total ;
1080 } /* pcm_read_bes2f */
1081
1082 static sf_count_t
1083 pcm_read_les2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
1084 {       int                     bufferlen, readcount ;
1085         sf_count_t      total = 0 ;
1086         float   normfact ;
1087
1088         normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x8000) : 1.0 ;
1089
1090         bufferlen = ARRAY_LEN (psf->u.sbuf) ;
1091
1092         while (len > 0)
1093         {       if (len < bufferlen)
1094                         bufferlen = (int) len ;
1095                 readcount = psf_fread (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
1096                 les2f_array (psf->u.sbuf, readcount, ptr + total, normfact) ;
1097                 total += readcount ;
1098                 if (readcount < bufferlen)
1099                         break ;
1100                 len -= readcount ;
1101                 } ;
1102
1103         return total ;
1104 } /* pcm_read_les2f */
1105
1106 static sf_count_t
1107 pcm_read_bet2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
1108 {       int                     bufferlen, readcount ;
1109         sf_count_t      total = 0 ;
1110         float   normfact ;
1111
1112         /* Special normfactor because tribyte value is read into an int. */
1113         normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x80000000) : 1.0 / 256.0 ;
1114
1115         bufferlen = sizeof (psf->u.ucbuf) / SIZEOF_TRIBYTE ;
1116
1117         while (len > 0)
1118         {       if (len < bufferlen)
1119                         bufferlen = (int) len ;
1120                 readcount = psf_fread (psf->u.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
1121                 bet2f_array ((tribyte*) (psf->u.ucbuf), readcount, ptr + total, normfact) ;
1122                 total += readcount ;
1123                 if (readcount < bufferlen)
1124                         break ;
1125                 len -= readcount ;
1126                 } ;
1127
1128         return total ;
1129 } /* pcm_read_bet2f */
1130
1131 static sf_count_t
1132 pcm_read_let2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
1133 {       int                     bufferlen, readcount ;
1134         sf_count_t      total = 0 ;
1135         float   normfact ;
1136
1137         /* Special normfactor because tribyte value is read into an int. */
1138         normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x80000000) : 1.0 / 256.0 ;
1139
1140         bufferlen = sizeof (psf->u.ucbuf) / SIZEOF_TRIBYTE ;
1141
1142         while (len > 0)
1143         {       if (len < bufferlen)
1144                         bufferlen = (int) len ;
1145                 readcount = psf_fread (psf->u.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
1146                 let2f_array ((tribyte*) (psf->u.ucbuf), readcount, ptr + total, normfact) ;
1147                 total += readcount ;
1148                 if (readcount < bufferlen)
1149                         break ;
1150                 len -= readcount ;
1151                 } ;
1152
1153         return total ;
1154 } /* pcm_read_let2f */
1155
1156 static sf_count_t
1157 pcm_read_bei2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
1158 {       int                     bufferlen, readcount ;
1159         sf_count_t      total = 0 ;
1160         float   normfact ;
1161
1162         normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x80000000) : 1.0 ;
1163
1164         bufferlen = ARRAY_LEN (psf->u.ibuf) ;
1165
1166         while (len > 0)
1167         {       if (len < bufferlen)
1168                         bufferlen = (int) len ;
1169                 readcount = psf_fread (psf->u.ibuf, sizeof (int), bufferlen, psf) ;
1170                 bei2f_array (psf->u.ibuf, readcount, ptr + total, normfact) ;
1171                 total += readcount ;
1172                 if (readcount < bufferlen)
1173                         break ;
1174                 len -= readcount ;
1175                 } ;
1176
1177         return total ;
1178 } /* pcm_read_bei2f */
1179
1180 static sf_count_t
1181 pcm_read_lei2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
1182 {       int                     bufferlen, readcount ;
1183         sf_count_t      total = 0 ;
1184         float   normfact ;
1185
1186         normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x80000000) : 1.0 ;
1187
1188         bufferlen = ARRAY_LEN (psf->u.ibuf) ;
1189
1190         while (len > 0)
1191         {       if (len < bufferlen)
1192                         bufferlen = (int) len ;
1193                 readcount = psf_fread (psf->u.ibuf, sizeof (int), bufferlen, psf) ;
1194                 lei2f_array (psf->u.ibuf, readcount, ptr + total, normfact) ;
1195                 total += readcount ;
1196                 if (readcount < bufferlen)
1197                         break ;
1198                 len -= readcount ;
1199                 } ;
1200
1201         return total ;
1202 } /* pcm_read_lei2f */
1203
1204 /*-----------------------------------------------------------------------------------------------
1205 */
1206
1207 static sf_count_t
1208 pcm_read_sc2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
1209 {       int                     bufferlen, readcount ;
1210         sf_count_t      total = 0 ;
1211         double          normfact ;
1212
1213         normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x80) : 1.0 ;
1214
1215         bufferlen = ARRAY_LEN (psf->u.scbuf) ;
1216
1217         while (len > 0)
1218         {       if (len < bufferlen)
1219                         bufferlen = (int) len ;
1220                 readcount = psf_fread (psf->u.scbuf, sizeof (signed char), bufferlen, psf) ;
1221                 sc2d_array (psf->u.scbuf, readcount, ptr + total, normfact) ;
1222                 total += readcount ;
1223                 if (readcount < bufferlen)
1224                         break ;
1225                 len -= readcount ;
1226                 } ;
1227
1228         return total ;
1229 } /* pcm_read_sc2d */
1230
1231 static sf_count_t
1232 pcm_read_uc2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
1233 {       int                     bufferlen, readcount ;
1234         sf_count_t      total = 0 ;
1235         double          normfact ;
1236
1237         normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x80) : 1.0 ;
1238
1239         bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
1240
1241         while (len > 0)
1242         {       if (len < bufferlen)
1243                         bufferlen = (int) len ;
1244                 readcount = psf_fread (psf->u.ucbuf, sizeof (unsigned char), bufferlen, psf) ;
1245                 uc2d_array (psf->u.ucbuf, readcount, ptr + total, normfact) ;
1246                 total += readcount ;
1247                 if (readcount < bufferlen)
1248                         break ;
1249                 len -= readcount ;
1250                 } ;
1251
1252         return total ;
1253 } /* pcm_read_uc2d */
1254
1255 static sf_count_t
1256 pcm_read_bes2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
1257 {       int                     bufferlen, readcount ;
1258         sf_count_t      total = 0 ;
1259         double          normfact ;
1260
1261         normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x8000) : 1.0 ;
1262
1263         bufferlen = ARRAY_LEN (psf->u.sbuf) ;
1264
1265         while (len > 0)
1266         {       if (len < bufferlen)
1267                         bufferlen = (int) len ;
1268                 readcount = psf_fread (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
1269                 bes2d_array (psf->u.sbuf, readcount, ptr + total, normfact) ;
1270                 total += readcount ;
1271                 if (readcount < bufferlen)
1272                         break ;
1273                 len -= readcount ;
1274                 } ;
1275
1276         return total ;
1277 } /* pcm_read_bes2d */
1278
1279 static sf_count_t
1280 pcm_read_les2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
1281 {       int                     bufferlen, readcount ;
1282         sf_count_t      total = 0 ;
1283         double          normfact ;
1284
1285         normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x8000) : 1.0 ;
1286
1287         bufferlen = ARRAY_LEN (psf->u.sbuf) ;
1288
1289         while (len > 0)
1290         {       if (len < bufferlen)
1291                         bufferlen = (int) len ;
1292                 readcount = psf_fread (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
1293                 les2d_array (psf->u.sbuf, readcount, ptr + total, normfact) ;
1294                 total += readcount ;
1295                 if (readcount < bufferlen)
1296                         break ;
1297                 len -= readcount ;
1298                 } ;
1299
1300         return total ;
1301 } /* pcm_read_les2d */
1302
1303 static sf_count_t
1304 pcm_read_bet2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
1305 {       int                     bufferlen, readcount ;
1306         sf_count_t      total = 0 ;
1307         double          normfact ;
1308
1309         normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x80000000) : 1.0 / 256.0 ;
1310
1311         bufferlen = sizeof (psf->u.ucbuf) / SIZEOF_TRIBYTE ;
1312
1313         while (len > 0)
1314         {       if (len < bufferlen)
1315                         bufferlen = (int) len ;
1316                 readcount = psf_fread (psf->u.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
1317                 bet2d_array ((tribyte*) (psf->u.ucbuf), readcount, ptr + total, normfact) ;
1318                 total += readcount ;
1319                 if (readcount < bufferlen)
1320                         break ;
1321                 len -= readcount ;
1322                 } ;
1323
1324         return total ;
1325 } /* pcm_read_bet2d */
1326
1327 static sf_count_t
1328 pcm_read_let2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
1329 {       int                     bufferlen, readcount ;
1330         sf_count_t      total = 0 ;
1331         double          normfact ;
1332
1333         /* Special normfactor because tribyte value is read into an int. */
1334         normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x80000000) : 1.0 / 256.0 ;
1335
1336         bufferlen = sizeof (psf->u.ucbuf) / SIZEOF_TRIBYTE ;
1337
1338         while (len > 0)
1339         {       if (len < bufferlen)
1340                         bufferlen = (int) len ;
1341                 readcount = psf_fread (psf->u.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
1342                 let2d_array ((tribyte*) (psf->u.ucbuf), readcount, ptr + total, normfact) ;
1343                 total += readcount ;
1344                 if (readcount < bufferlen)
1345                         break ;
1346                 len -= readcount ;
1347                 } ;
1348
1349         return total ;
1350 } /* pcm_read_let2d */
1351
1352 static sf_count_t
1353 pcm_read_bei2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
1354 {       int                     bufferlen, readcount ;
1355         sf_count_t      total = 0 ;
1356         double          normfact ;
1357
1358         normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x80000000) : 1.0 ;
1359
1360         bufferlen = ARRAY_LEN (psf->u.ibuf) ;
1361
1362         while (len > 0)
1363         {       if (len < bufferlen)
1364                         bufferlen = (int) len ;
1365                 readcount = psf_fread (psf->u.ibuf, sizeof (int), bufferlen, psf) ;
1366                 bei2d_array (psf->u.ibuf, readcount, ptr + total, normfact) ;
1367                 total += readcount ;
1368                 if (readcount < bufferlen)
1369                         break ;
1370                 len -= readcount ;
1371                 } ;
1372
1373         return total ;
1374 } /* pcm_read_bei2d */
1375
1376 static sf_count_t
1377 pcm_read_lei2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
1378 {       int                     bufferlen, readcount ;
1379         sf_count_t      total = 0 ;
1380         double          normfact ;
1381
1382         normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x80000000) : 1.0 ;
1383
1384         bufferlen = ARRAY_LEN (psf->u.ibuf) ;
1385
1386         while (len > 0)
1387         {       if (len < bufferlen)
1388                         bufferlen = (int) len ;
1389                 readcount = psf_fread (psf->u.ibuf, sizeof (int), bufferlen, psf) ;
1390                 lei2d_array (psf->u.ibuf, readcount, ptr + total, normfact) ;
1391                 total += readcount ;
1392                 if (readcount < bufferlen)
1393                         break ;
1394                 len -= readcount ;
1395                 } ;
1396
1397         return total ;
1398 } /* pcm_read_lei2d */
1399
1400 /*===============================================================================================
1401 **-----------------------------------------------------------------------------------------------
1402 **===============================================================================================
1403 */
1404
1405 static sf_count_t
1406 pcm_write_s2sc  (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
1407 {       int                     bufferlen, writecount ;
1408         sf_count_t      total = 0 ;
1409
1410         bufferlen = ARRAY_LEN (psf->u.scbuf) ;
1411
1412         while (len > 0)
1413         {       if (len < bufferlen)
1414                         bufferlen = (int) len ;
1415                 s2sc_array (ptr + total, psf->u.scbuf, bufferlen) ;
1416                 writecount = psf_fwrite (psf->u.scbuf, sizeof (signed char), bufferlen, psf) ;
1417                 total += writecount ;
1418                 if (writecount < bufferlen)
1419                         break ;
1420                 len -= writecount ;
1421                 } ;
1422
1423         return total ;
1424 } /* pcm_write_s2sc */
1425
1426 static sf_count_t
1427 pcm_write_s2uc  (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
1428 {       int                     bufferlen, writecount ;
1429         sf_count_t      total = 0 ;
1430
1431         bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
1432
1433         while (len > 0)
1434         {       if (len < bufferlen)
1435                         bufferlen = (int) len ;
1436                 s2uc_array (ptr + total, psf->u.ucbuf, bufferlen) ;
1437                 writecount = psf_fwrite (psf->u.ucbuf, sizeof (unsigned char), bufferlen, psf) ;
1438                 total += writecount ;
1439                 if (writecount < bufferlen)
1440                         break ;
1441                 len -= writecount ;
1442                 } ;
1443
1444         return total ;
1445 } /* pcm_write_s2uc */
1446
1447 static sf_count_t
1448 pcm_write_s2bes (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
1449 {       int                     bufferlen, writecount ;
1450         sf_count_t      total = 0 ;
1451
1452         if (CPU_IS_BIG_ENDIAN)
1453                 return psf_fwrite (ptr, sizeof (short), len, psf) ;
1454         else
1455
1456         bufferlen = ARRAY_LEN (psf->u.sbuf) ;
1457
1458         while (len > 0)
1459         {       if (len < bufferlen)
1460                         bufferlen = (int) len ;
1461                 endswap_short_copy (psf->u.sbuf, ptr + total, bufferlen) ;
1462                 writecount = psf_fwrite (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
1463                 total += writecount ;
1464                 if (writecount < bufferlen)
1465                         break ;
1466                 len -= writecount ;
1467                 } ;
1468
1469         return total ;
1470 } /* pcm_write_s2bes */
1471
1472 static sf_count_t
1473 pcm_write_s2les (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
1474 {       int                     bufferlen, writecount ;
1475         sf_count_t      total = 0 ;
1476
1477         if (CPU_IS_LITTLE_ENDIAN)
1478                 return psf_fwrite (ptr, sizeof (short), len, psf) ;
1479
1480         bufferlen = ARRAY_LEN (psf->u.sbuf) ;
1481
1482         while (len > 0)
1483         {       if (len < bufferlen)
1484                         bufferlen = (int) len ;
1485                 endswap_short_copy (psf->u.sbuf, ptr + total, bufferlen) ;
1486                 writecount = psf_fwrite (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
1487                 total += writecount ;
1488                 if (writecount < bufferlen)
1489                         break ;
1490                 len -= writecount ;
1491                 } ;
1492
1493         return total ;
1494 } /* pcm_write_s2les */
1495
1496 static sf_count_t
1497 pcm_write_s2bet (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
1498 {       int                     bufferlen, writecount ;
1499         sf_count_t      total = 0 ;
1500
1501         bufferlen = sizeof (psf->u.ucbuf) / SIZEOF_TRIBYTE ;
1502
1503         while (len > 0)
1504         {       if (len < bufferlen)
1505                         bufferlen = (int) len ;
1506                 s2bet_array (ptr + total, (tribyte*) (psf->u.ucbuf), bufferlen) ;
1507                 writecount = psf_fwrite (psf->u.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
1508                 total += writecount ;
1509                 if (writecount < bufferlen)
1510                         break ;
1511                 len -= writecount ;
1512                 } ;
1513
1514         return total ;
1515 } /* pcm_write_s2bet */
1516
1517 static sf_count_t
1518 pcm_write_s2let (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
1519 {       int                     bufferlen, writecount ;
1520         sf_count_t      total = 0 ;
1521
1522         bufferlen = sizeof (psf->u.ucbuf) / SIZEOF_TRIBYTE ;
1523
1524         while (len > 0)
1525         {       if (len < bufferlen)
1526                         bufferlen = (int) len ;
1527                 s2let_array (ptr + total, (tribyte*) (psf->u.ucbuf), bufferlen) ;
1528                 writecount = psf_fwrite (psf->u.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
1529                 total += writecount ;
1530                 if (writecount < bufferlen)
1531                         break ;
1532                 len -= writecount ;
1533                 } ;
1534
1535         return total ;
1536 } /* pcm_write_s2let */
1537
1538 static sf_count_t
1539 pcm_write_s2bei (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
1540 {       int                     bufferlen, writecount ;
1541         sf_count_t      total = 0 ;
1542
1543         bufferlen = ARRAY_LEN (psf->u.ibuf) ;
1544
1545         while (len > 0)
1546         {       if (len < bufferlen)
1547                         bufferlen = (int) len ;
1548                 s2bei_array (ptr + total, psf->u.ibuf, bufferlen) ;
1549                 writecount = psf_fwrite (psf->u.ibuf, sizeof (int), bufferlen, psf) ;
1550                 total += writecount ;
1551                 if (writecount < bufferlen)
1552                         break ;
1553                 len -= writecount ;
1554                 } ;
1555
1556         return total ;
1557 } /* pcm_write_s2bei */
1558
1559 static sf_count_t
1560 pcm_write_s2lei (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
1561 {       int                     bufferlen, writecount ;
1562         sf_count_t      total = 0 ;
1563
1564         bufferlen = ARRAY_LEN (psf->u.ibuf) ;
1565
1566         while (len > 0)
1567         {       if (len < bufferlen)
1568                         bufferlen = (int) len ;
1569                 s2lei_array (ptr + total, psf->u.ibuf, bufferlen) ;
1570                 writecount = psf_fwrite (psf->u.ibuf, sizeof (int), bufferlen, psf) ;
1571                 total += writecount ;
1572                 if (writecount < bufferlen)
1573                         break ;
1574                 len -= writecount ;
1575                 } ;
1576
1577         return total ;
1578 } /* pcm_write_s2lei */
1579
1580 /*-----------------------------------------------------------------------------------------------
1581 */
1582
1583 static sf_count_t
1584 pcm_write_i2sc  (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
1585 {       int                     bufferlen, writecount ;
1586         sf_count_t      total = 0 ;
1587
1588         bufferlen = ARRAY_LEN (psf->u.scbuf) ;
1589
1590         while (len > 0)
1591         {       if (len < bufferlen)
1592                         bufferlen = (int) len ;
1593                 i2sc_array (ptr + total, psf->u.scbuf, bufferlen) ;
1594                 writecount = psf_fwrite (psf->u.scbuf, sizeof (signed char), bufferlen, psf) ;
1595                 total += writecount ;
1596                 if (writecount < bufferlen)
1597                         break ;
1598                 len -= writecount ;
1599                 } ;
1600
1601         return total ;
1602 } /* pcm_write_i2sc */
1603
1604 static sf_count_t
1605 pcm_write_i2uc  (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
1606 {       int                     bufferlen, writecount ;
1607         sf_count_t      total = 0 ;
1608
1609         bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
1610
1611         while (len > 0)
1612         {       if (len < bufferlen)
1613                         bufferlen = (int) len ;
1614                 i2uc_array (ptr + total, psf->u.ucbuf, bufferlen) ;
1615                 writecount = psf_fwrite (psf->u.ucbuf, sizeof (signed char), bufferlen, psf) ;
1616                 total += writecount ;
1617                 if (writecount < bufferlen)
1618                         break ;
1619                 len -= writecount ;
1620                 } ;
1621
1622         return total ;
1623 } /* pcm_write_i2uc */
1624
1625 static sf_count_t
1626 pcm_write_i2bes (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
1627 {       int                     bufferlen, writecount ;
1628         sf_count_t      total = 0 ;
1629
1630         bufferlen = ARRAY_LEN (psf->u.sbuf) ;
1631
1632         while (len > 0)
1633         {       if (len < bufferlen)
1634                         bufferlen = (int) len ;
1635                 i2bes_array (ptr + total, psf->u.sbuf, bufferlen) ;
1636                 writecount = psf_fwrite (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
1637                 total += writecount ;
1638                 if (writecount < bufferlen)
1639                         break ;
1640                 len -= writecount ;
1641                 } ;
1642
1643         return total ;
1644 } /* pcm_write_i2bes */
1645
1646 static sf_count_t
1647 pcm_write_i2les (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
1648 {       int                     bufferlen, writecount ;
1649         sf_count_t      total = 0 ;
1650
1651         bufferlen = ARRAY_LEN (psf->u.sbuf) ;
1652
1653         while (len > 0)
1654         {       if (len < bufferlen)
1655                         bufferlen = (int) len ;
1656                 i2les_array (ptr + total, psf->u.sbuf, bufferlen) ;
1657                 writecount = psf_fwrite (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
1658                 total += writecount ;
1659                 if (writecount < bufferlen)
1660                         break ;
1661                 len -= writecount ;
1662                 } ;
1663
1664         return total ;
1665 } /* pcm_write_i2les */
1666
1667 static sf_count_t
1668 pcm_write_i2bet (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
1669 {       int                     bufferlen, writecount ;
1670         sf_count_t      total = 0 ;
1671
1672         bufferlen = sizeof (psf->u.ucbuf) / SIZEOF_TRIBYTE ;
1673
1674         while (len > 0)
1675         {       if (len < bufferlen)
1676                         bufferlen = (int) len ;
1677                 i2bet_array (ptr + total, (tribyte*) (psf->u.ucbuf), bufferlen) ;
1678                 writecount = psf_fwrite (psf->u.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
1679                 total += writecount ;
1680                 if (writecount < bufferlen)
1681                         break ;
1682                 len -= writecount ;
1683                 } ;
1684
1685         return total ;
1686 } /* pcm_write_i2bet */
1687
1688 static sf_count_t
1689 pcm_write_i2let (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
1690 {       int                     bufferlen, writecount ;
1691         sf_count_t      total = 0 ;
1692
1693         bufferlen = sizeof (psf->u.ucbuf) / SIZEOF_TRIBYTE ;
1694
1695         while (len > 0)
1696         {       if (len < bufferlen)
1697                         bufferlen = (int) len ;
1698                 i2let_array (ptr + total, (tribyte*) (psf->u.ucbuf), bufferlen) ;
1699                 writecount = psf_fwrite (psf->u.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
1700                 total += writecount ;
1701                 if (writecount < bufferlen)
1702                         break ;
1703                 len -= writecount ;
1704                 } ;
1705
1706         return total ;
1707 } /* pcm_write_i2les */
1708
1709 static sf_count_t
1710 pcm_write_i2bei (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
1711 {       int                     bufferlen, writecount ;
1712         sf_count_t      total = 0 ;
1713
1714         if (CPU_IS_BIG_ENDIAN)
1715                 return psf_fwrite (ptr, sizeof (int), len, psf) ;
1716
1717         bufferlen = ARRAY_LEN (psf->u.ibuf) ;
1718
1719         while (len > 0)
1720         {       if (len < bufferlen)
1721                         bufferlen = (int) len ;
1722                 endswap_int_copy (psf->u.ibuf, ptr + total, bufferlen) ;
1723                 writecount = psf_fwrite (psf->u.ibuf, sizeof (int), bufferlen, psf) ;
1724                 total += writecount ;
1725                 if (writecount < bufferlen)
1726                         break ;
1727                 len -= writecount ;
1728                 } ;
1729
1730         return total ;
1731 } /* pcm_write_i2bei */
1732
1733 static sf_count_t
1734 pcm_write_i2lei (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
1735 {       int                     bufferlen, writecount ;
1736         sf_count_t      total = 0 ;
1737
1738         if (CPU_IS_LITTLE_ENDIAN)
1739                 return psf_fwrite (ptr, sizeof (int), len, psf) ;
1740
1741         bufferlen = ARRAY_LEN (psf->u.ibuf) ;
1742
1743         while (len > 0)
1744         {       if (len < bufferlen)
1745                         bufferlen = (int) len ;
1746                 endswap_int_copy (psf->u.ibuf, ptr + total, bufferlen) ;
1747                 writecount = psf_fwrite (psf->u.ibuf, sizeof (int), bufferlen, psf) ;
1748                 total += writecount ;
1749                 if (writecount < bufferlen)
1750                         break ;
1751                 len -= writecount ;
1752                 } ;
1753
1754         return total ;
1755 } /* pcm_write_i2lei */
1756
1757 /*------------------------------------------------------------------------------
1758 **==============================================================================
1759 **------------------------------------------------------------------------------
1760 */
1761
1762 static void
1763 f2sc_array (const float *src, signed char *dest, int count, int normalize)
1764 {       float normfact ;
1765
1766         normfact = normalize ? (1.0 * 0x7F) : 1.0 ;
1767
1768         while (--count >= 0)
1769         {       dest [count] = lrintf (src [count] * normfact) ;
1770                 } ;
1771 } /* f2sc_array */
1772
1773 static void
1774 f2sc_clip_array (const float *src, signed char *dest, int count, int normalize)
1775 {       float   normfact, scaled_value ;
1776
1777         normfact = normalize ? (8.0 * 0x10000000) : (1.0 * 0x1000000) ;
1778
1779         while (--count >= 0)
1780         {       scaled_value = src [count] * normfact ;
1781                 if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
1782                 {       dest [count] = 127 ;
1783                         continue ;
1784                         } ;
1785                 if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
1786                 {       dest [count] = -128 ;
1787                         continue ;
1788                         } ;
1789
1790                 dest [count] = lrintf (scaled_value) >> 24 ;
1791                 } ;
1792 } /* f2sc_clip_array */
1793
1794 static sf_count_t
1795 pcm_write_f2sc  (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
1796 {       void            (*convert) (const float *, signed char *, int, int) ;
1797         int                     bufferlen, writecount ;
1798         sf_count_t      total = 0 ;
1799
1800         convert = (psf->add_clipping) ? f2sc_clip_array : f2sc_array ;
1801         bufferlen = ARRAY_LEN (psf->u.scbuf) ;
1802
1803         while (len > 0)
1804         {       if (len < bufferlen)
1805                         bufferlen = (int) len ;
1806                 convert (ptr + total, psf->u.scbuf, bufferlen, psf->norm_float) ;
1807                 writecount = psf_fwrite (psf->u.scbuf, sizeof (signed char), bufferlen, psf) ;
1808                 total += writecount ;
1809                 if (writecount < bufferlen)
1810                         break ;
1811                 len -= writecount ;
1812                 } ;
1813
1814         return total ;
1815 } /* pcm_write_f2sc */
1816
1817 /*==============================================================================
1818 */
1819
1820 static  void
1821 f2uc_array      (const float *src, unsigned char *dest, int count, int normalize)
1822 {       float normfact ;
1823
1824         normfact = normalize ? (1.0 * 0x7F) : 1.0 ;
1825
1826         while (--count >= 0)
1827         {       dest [count] = lrintf (src [count] * normfact) + 128 ;
1828                 } ;
1829 } /* f2uc_array */
1830
1831 static  void
1832 f2uc_clip_array (const float *src, unsigned char *dest, int count, int normalize)
1833 {       float   normfact, scaled_value ;
1834
1835         normfact = normalize ? (8.0 * 0x10000000) : (1.0 * 0x1000000) ;
1836
1837         while (--count >= 0)
1838         {       scaled_value = src [count] * normfact ;
1839                 if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
1840                 {       dest [count] = 0xFF ;
1841                         continue ;
1842                         } ;
1843                 if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
1844                 {       dest [count] = 0 ;
1845                         continue ;
1846                         } ;
1847
1848                 dest [count] = (lrintf (scaled_value) >> 24) + 128 ;
1849                 } ;
1850 } /* f2uc_clip_array */
1851
1852 static sf_count_t
1853 pcm_write_f2uc  (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
1854 {       void            (*convert) (const float *, unsigned char *, int, int) ;
1855         int                     bufferlen, writecount ;
1856         sf_count_t      total = 0 ;
1857
1858         convert = (psf->add_clipping) ? f2uc_clip_array : f2uc_array ;
1859         bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
1860
1861         while (len > 0)
1862         {       if (len < bufferlen)
1863                         bufferlen = (int) len ;
1864                 convert (ptr + total, psf->u.ucbuf, bufferlen, psf->norm_float) ;
1865                 writecount = psf_fwrite (psf->u.ucbuf, sizeof (unsigned char), bufferlen, psf) ;
1866                 total += writecount ;
1867                 if (writecount < bufferlen)
1868                         break ;
1869                 len -= writecount ;
1870                 } ;
1871
1872         return total ;
1873 } /* pcm_write_f2uc */
1874
1875 /*==============================================================================
1876 */
1877
1878 static void
1879 f2bes_array (const float *src, short *dest, int count, int normalize)
1880 {       unsigned char   *ucptr ;
1881         float                   normfact ;
1882         short                   value ;
1883
1884         normfact = normalize ? (1.0 * 0x7FFF) : 1.0 ;
1885         ucptr = ((unsigned char*) dest) + 2 * count ;
1886
1887         while (--count >= 0)
1888         {       ucptr -= 2 ;
1889                 value = lrintf (src [count] * normfact) ;
1890                 ucptr [1] = value ;
1891                 ucptr [0] = value >> 8 ;
1892                         } ;
1893 } /* f2bes_array */
1894
1895 static void
1896 f2bes_clip_array (const float *src, short *dest, int count, int normalize)
1897 {       unsigned char   *ucptr ;
1898         float                   normfact, scaled_value ;
1899         int                             value ;
1900
1901         normfact = normalize ? (8.0 * 0x10000000) : (1.0 * 0x10000) ;
1902         ucptr = ((unsigned char*) dest) + 2 * count ;
1903
1904         while (--count >= 0)
1905         {       ucptr -= 2 ;
1906                 scaled_value = src [count] * normfact ;
1907                 if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
1908                 {       ucptr [1] = 0xFF ;
1909                         ucptr [0] = 0x7F ;
1910                         continue ;
1911                 } ;
1912                 if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
1913                 {       ucptr [1] = 0x00 ;
1914                         ucptr [0] = 0x80 ;
1915                         continue ;
1916                         } ;
1917
1918                 value = lrintf (scaled_value) ;
1919                 ucptr [1] = value >> 16 ;
1920                 ucptr [0] = value >> 24 ;
1921                 } ;
1922 } /* f2bes_clip_array */
1923
1924 static sf_count_t
1925 pcm_write_f2bes (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
1926 {       void            (*convert) (const float *, short *t, int, int) ;
1927         int                     bufferlen, writecount ;
1928         sf_count_t      total = 0 ;
1929
1930         convert = (psf->add_clipping) ? f2bes_clip_array : f2bes_array ;
1931         bufferlen = ARRAY_LEN (psf->u.sbuf) ;
1932
1933         while (len > 0)
1934         {       if (len < bufferlen)
1935                         bufferlen = (int) len ;
1936                 convert (ptr + total, psf->u.sbuf, bufferlen, psf->norm_float) ;
1937                 writecount = psf_fwrite (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
1938                 total += writecount ;
1939                 if (writecount < bufferlen)
1940                                 break ;
1941                 len -= writecount ;
1942                 } ;
1943
1944         return total ;
1945 } /* pcm_write_f2bes */
1946
1947 /*==============================================================================
1948 */
1949
1950 static void
1951 f2les_array (const float *src, short *dest, int count, int normalize)
1952 {       unsigned char   *ucptr ;
1953         float                   normfact ;
1954         int                             value ;
1955
1956         normfact = normalize ? (1.0 * 0x7FFF) : 1.0 ;
1957         ucptr = ((unsigned char*) dest) + 2 * count ;
1958
1959         while (--count >= 0)
1960         {       ucptr -= 2 ;
1961                 value = lrintf (src [count] * normfact) ;
1962                 ucptr [0] = value ;
1963                 ucptr [1] = value >> 8 ;
1964                 } ;
1965 } /* f2les_array */
1966
1967 static void
1968 f2les_clip_array (const float *src, short *dest, int count, int normalize)
1969 {       unsigned char   *ucptr ;
1970         float                   normfact, scaled_value ;
1971         int                             value ;
1972
1973         normfact = normalize ? (8.0 * 0x10000000) : (1.0 * 0x10000) ;
1974         ucptr = ((unsigned char*) dest) + 2 * count ;
1975
1976         while (--count >= 0)
1977         {       ucptr -= 2 ;
1978                 scaled_value = src [count] * normfact ;
1979                 if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
1980                 {       ucptr [0] = 0xFF ;
1981                         ucptr [1] = 0x7F ;
1982                         continue ;
1983                         } ;
1984                 if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
1985                 {       ucptr [0] = 0x00 ;
1986                         ucptr [1] = 0x80 ;
1987                         continue ;
1988                         } ;
1989
1990                 value = lrintf (scaled_value) ;
1991                 ucptr [0] = value >> 16 ;
1992                 ucptr [1] = value >> 24 ;
1993                 } ;
1994 } /* f2les_clip_array */
1995
1996 static sf_count_t
1997 pcm_write_f2les (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
1998 {       void            (*convert) (const float *, short *t, int, int) ;
1999         int                     bufferlen, writecount ;
2000         sf_count_t      total = 0 ;
2001
2002         convert = (psf->add_clipping) ? f2les_clip_array : f2les_array ;
2003         bufferlen = ARRAY_LEN (psf->u.sbuf) ;
2004
2005         while (len > 0)
2006         {       if (len < bufferlen)
2007                         bufferlen = (int) len ;
2008                 convert (ptr + total, psf->u.sbuf, bufferlen, psf->norm_float) ;
2009                 writecount = psf_fwrite (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
2010                 total += writecount ;
2011                 if (writecount < bufferlen)
2012                         break ;
2013                 len -= writecount ;
2014                 } ;
2015
2016         return total ;
2017 } /* pcm_write_f2les */
2018
2019 /*==============================================================================
2020 */
2021
2022 static void
2023 f2let_array (const float *src, tribyte *dest, int count, int normalize)
2024 {       unsigned char   *ucptr ;
2025         float                   normfact ;
2026         int                             value ;
2027
2028         normfact = normalize ? (1.0 * 0x7FFFFF) : 1.0 ;
2029         ucptr = ((unsigned char*) dest) + 3 * count ;
2030
2031         while (--count >= 0)
2032         {       ucptr -= 3 ;
2033                 value = lrintf (src [count] * normfact) ;
2034                 ucptr [0] = value ;
2035                 ucptr [1] = value >> 8 ;
2036                 ucptr [2] = value >> 16 ;
2037                 } ;
2038 } /* f2let_array */
2039
2040 static void
2041 f2let_clip_array (const float *src, tribyte *dest, int count, int normalize)
2042 {       unsigned char   *ucptr ;
2043         float                   normfact, scaled_value ;
2044         int                             value ;
2045
2046         normfact = normalize ? (8.0 * 0x10000000) : (1.0 * 0x100) ;
2047         ucptr = ((unsigned char*) dest) + 3 * count ;
2048
2049         while (--count >= 0)
2050         {       ucptr -= 3 ;
2051                 scaled_value = src [count] * normfact ;
2052                 if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
2053                 {       ucptr [0] = 0xFF ;
2054                         ucptr [1] = 0xFF ;
2055                         ucptr [2] = 0x7F ;
2056                         continue ;
2057                         } ;
2058                 if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
2059                 {       ucptr [0] = 0x00 ;
2060                         ucptr [1] = 0x00 ;
2061                         ucptr [2] = 0x80 ;
2062                         continue ;
2063                 } ;
2064
2065                 value = lrintf (scaled_value) ;
2066                 ucptr [0] = value >> 8 ;
2067                 ucptr [1] = value >> 16 ;
2068                 ucptr [2] = value >> 24 ;
2069                 } ;
2070 } /* f2let_clip_array */
2071
2072 static sf_count_t
2073 pcm_write_f2let (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
2074 {       void            (*convert) (const float *, tribyte *, int, int) ;
2075         int                     bufferlen, writecount ;
2076         sf_count_t      total = 0 ;
2077
2078         convert = (psf->add_clipping) ? f2let_clip_array : f2let_array ;
2079         bufferlen = sizeof (psf->u.ucbuf) / SIZEOF_TRIBYTE ;
2080
2081         while (len > 0)
2082         {       if (len < bufferlen)
2083                         bufferlen = (int) len ;
2084                 convert (ptr + total, (tribyte*) (psf->u.ucbuf), bufferlen, psf->norm_float) ;
2085                 writecount = psf_fwrite (psf->u.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
2086                 total += writecount ;
2087                 if (writecount < bufferlen)
2088                         break ;
2089                 len -= writecount ;
2090                 } ;
2091
2092         return total ;
2093 } /* pcm_write_f2let */
2094
2095 /*==============================================================================
2096 */
2097
2098 static void
2099 f2bet_array (const float *src, tribyte *dest, int count, int normalize)
2100 {       unsigned char   *ucptr ;
2101         float                   normfact ;
2102         int                             value ;
2103
2104         normfact = normalize ? (1.0 * 0x7FFFFF) : 1.0 ;
2105         ucptr = ((unsigned char*) dest) + 3 * count ;
2106
2107         while (--count >= 0)
2108         {       ucptr -= 3 ;
2109                 value = lrintf (src [count] * normfact) ;
2110                 ucptr [0] = value >> 16 ;
2111                 ucptr [1] = value >> 8 ;
2112                 ucptr [2] = value ;
2113                 } ;
2114 } /* f2bet_array */
2115
2116 static void
2117 f2bet_clip_array (const float *src, tribyte *dest, int count, int normalize)
2118 {       unsigned char   *ucptr ;
2119         float                   normfact, scaled_value ;
2120         int                             value ;
2121
2122         normfact = normalize ? (8.0 * 0x10000000) : (1.0 * 0x100) ;
2123         ucptr = ((unsigned char*) dest) + 3 * count ;
2124
2125         while (--count >= 0)
2126         {       ucptr -= 3 ;
2127                 scaled_value = src [count] * normfact ;
2128                 if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
2129                 {       ucptr [0] = 0x7F ;
2130                         ucptr [1] = 0xFF ;
2131                         ucptr [2] = 0xFF ;
2132                         continue ;
2133                         } ;
2134                 if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
2135                 {       ucptr [0] = 0x80 ;
2136                         ucptr [1] = 0x00 ;
2137                         ucptr [2] = 0x00 ;
2138                         continue ;
2139                 } ;
2140
2141                 value = lrint (scaled_value) ;
2142                 ucptr [0] = value >> 24 ;
2143                 ucptr [1] = value >> 16 ;
2144                 ucptr [2] = value >> 8 ;
2145                 } ;
2146 } /* f2bet_clip_array */
2147
2148 static sf_count_t
2149 pcm_write_f2bet (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
2150 {       void            (*convert) (const float *, tribyte *, int, int) ;
2151         int                     bufferlen, writecount ;
2152         sf_count_t      total = 0 ;
2153
2154         convert = (psf->add_clipping) ? f2bet_clip_array : f2bet_array ;
2155         bufferlen = sizeof (psf->u.ucbuf) / SIZEOF_TRIBYTE ;
2156
2157         while (len > 0)
2158         {       if (len < bufferlen)
2159                         bufferlen = (int) len ;
2160                 convert (ptr + total, (tribyte*) (psf->u.ucbuf), bufferlen, psf->norm_float) ;
2161                 writecount = psf_fwrite (psf->u.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
2162                 total += writecount ;
2163                 if (writecount < bufferlen)
2164                         break ;
2165                 len -= writecount ;
2166                 } ;
2167
2168         return total ;
2169 } /* pcm_write_f2bet */
2170
2171 /*==============================================================================
2172 */
2173
2174 static void
2175 f2bei_array (const float *src, int *dest, int count, int normalize)
2176 {       unsigned char   *ucptr ;
2177         float                   normfact ;
2178         int                             value ;
2179
2180         normfact = normalize ? (1.0 * 0x7FFFFFFF) : 1.0 ;
2181         ucptr = ((unsigned char*) dest) + 4 * count ;
2182         while (--count >= 0)
2183         {       ucptr -= 4 ;
2184                 value = lrintf (src [count] * normfact) ;
2185                 ucptr [0] = value >> 24 ;
2186                 ucptr [1] = value >> 16 ;
2187                 ucptr [2] = value >> 8 ;
2188                 ucptr [3] = value ;
2189                 } ;
2190 } /* f2bei_array */
2191
2192 static void
2193 f2bei_clip_array (const float *src, int *dest, int count, int normalize)
2194 {       unsigned char   *ucptr ;
2195         float                   normfact, scaled_value ;
2196         int                             value ;
2197
2198         normfact = normalize ? (8.0 * 0x10000000) : 1.0 ;
2199         ucptr = ((unsigned char*) dest) + 4 * count ;
2200
2201         while (--count >= 0)
2202         {       ucptr -= 4 ;
2203                 scaled_value = src [count] * normfact ;
2204                 if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= 1.0 * 0x7FFFFFFF)
2205                 {       ucptr [0] = 0x7F ;
2206                         ucptr [1] = 0xFF ;
2207                         ucptr [2] = 0xFF ;
2208                         ucptr [3] = 0xFF ;
2209                         continue ;
2210                         } ;
2211                 if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
2212                 {       ucptr [0] = 0x80 ;
2213                         ucptr [1] = 0x00 ;
2214                         ucptr [2] = 0x00 ;
2215                         ucptr [3] = 0x00 ;
2216                         continue ;
2217                 } ;
2218
2219                 value = lrintf (scaled_value) ;
2220                 ucptr [0] = value >> 24 ;
2221                 ucptr [1] = value >> 16 ;
2222                 ucptr [2] = value >> 8 ;
2223                 ucptr [3] = value ;
2224                 } ;
2225 } /* f2bei_clip_array */
2226
2227 static sf_count_t
2228 pcm_write_f2bei (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
2229 {       void            (*convert) (const float *, int *, int, int) ;
2230         int                     bufferlen, writecount ;
2231         sf_count_t      total = 0 ;
2232
2233         convert = (psf->add_clipping) ? f2bei_clip_array : f2bei_array ;
2234         bufferlen = ARRAY_LEN (psf->u.ibuf) ;
2235
2236         while (len > 0)
2237         {       if (len < bufferlen)
2238                         bufferlen = (int) len ;
2239                 convert (ptr + total, psf->u.ibuf, bufferlen, psf->norm_float) ;
2240                 writecount = psf_fwrite (psf->u.ibuf, sizeof (int), bufferlen, psf) ;
2241                 total += writecount ;
2242                 if (writecount < bufferlen)
2243                         break ;
2244                 len -= writecount ;
2245                 } ;
2246
2247         return total ;
2248 } /* pcm_write_f2bei */
2249
2250 /*==============================================================================
2251 */
2252
2253 static void
2254 f2lei_array (const float *src, int *dest, int count, int normalize)
2255 {       unsigned char   *ucptr ;
2256         float                   normfact ;
2257         int                             value ;
2258
2259         normfact = normalize ? (1.0 * 0x7FFFFFFF) : 1.0 ;
2260         ucptr = ((unsigned char*) dest) + 4 * count ;
2261
2262         while (--count >= 0)
2263         {       ucptr -= 4 ;
2264                 value = lrintf (src [count] * normfact) ;
2265                 ucptr [0] = value ;
2266                 ucptr [1] = value >> 8 ;
2267                 ucptr [2] = value >> 16 ;
2268                 ucptr [3] = value >> 24 ;
2269                 } ;
2270 } /* f2lei_array */
2271
2272 static void
2273 f2lei_clip_array (const float *src, int *dest, int count, int normalize)
2274 {       unsigned char   *ucptr ;
2275         float                   normfact, scaled_value ;
2276         int                             value ;
2277
2278         normfact = normalize ? (8.0 * 0x10000000) : 1.0 ;
2279         ucptr = ((unsigned char*) dest) + 4 * count ;
2280
2281         while (--count >= 0)
2282         {       ucptr -= 4 ;
2283                 scaled_value = src [count] * normfact ;
2284                 if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
2285                 {       ucptr [0] = 0xFF ;
2286                         ucptr [1] = 0xFF ;
2287                         ucptr [2] = 0xFF ;
2288                         ucptr [3] = 0x7F ;
2289                         continue ;
2290                         } ;
2291                 if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
2292                 {       ucptr [0] = 0x00 ;
2293                         ucptr [1] = 0x00 ;
2294                         ucptr [2] = 0x00 ;
2295                         ucptr [3] = 0x80 ;
2296                         continue ;
2297                         } ;
2298
2299                 value = lrintf (scaled_value) ;
2300                 ucptr [0] = value ;
2301                 ucptr [1] = value >> 8 ;
2302                 ucptr [2] = value >> 16 ;
2303                 ucptr [3] = value >> 24 ;
2304                 } ;
2305 } /* f2lei_clip_array */
2306
2307 static sf_count_t
2308 pcm_write_f2lei (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
2309 {       void            (*convert) (const float *, int *, int, int) ;
2310         int                     bufferlen, writecount ;
2311         sf_count_t      total = 0 ;
2312
2313         convert = (psf->add_clipping) ? f2lei_clip_array : f2lei_array ;
2314         bufferlen = ARRAY_LEN (psf->u.ibuf) ;
2315
2316         while (len > 0)
2317         {       if (len < bufferlen)
2318                         bufferlen = (int) len ;
2319                 convert (ptr + total, psf->u.ibuf, bufferlen, psf->norm_float) ;
2320                 writecount = psf_fwrite (psf->u.ibuf, sizeof (int), bufferlen, psf) ;
2321                 total += writecount ;
2322                 if (writecount < bufferlen)
2323                         break ;
2324                 len -= writecount ;
2325                 } ;
2326
2327         return total ;
2328 } /* pcm_write_f2lei */
2329
2330 /*==============================================================================
2331 */
2332
2333 static void
2334 d2sc_array      (const double *src, signed char *dest, int count, int normalize)
2335 {       double  normfact ;
2336
2337         normfact = normalize ? (1.0 * 0x7F) : 1.0 ;
2338
2339         while (--count >= 0)
2340         {       dest [count] = lrint (src [count] * normfact) ;
2341                 } ;
2342 } /* d2sc_array */
2343
2344 static void
2345 d2sc_clip_array (const double *src, signed char *dest, int count, int normalize)
2346 {       double  normfact, scaled_value ;
2347
2348         normfact = normalize ? (8.0 * 0x10000000) : (1.0 * 0x1000000) ;
2349
2350         while (--count >= 0)
2351         {       scaled_value = src [count] * normfact ;
2352                 if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
2353                 {       dest [count] = 127 ;
2354                         continue ;
2355                         } ;
2356                 if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
2357                 {       dest [count] = -128 ;
2358                         continue ;
2359                         } ;
2360
2361                 dest [count] = lrintf (scaled_value) >> 24 ;
2362                 } ;
2363 } /* d2sc_clip_array */
2364
2365 static sf_count_t
2366 pcm_write_d2sc  (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
2367 {       void            (*convert) (const double *, signed char *, int, int) ;
2368         int                     bufferlen, writecount ;
2369         sf_count_t      total = 0 ;
2370
2371         convert = (psf->add_clipping) ? d2sc_clip_array : d2sc_array ;
2372         bufferlen = ARRAY_LEN (psf->u.scbuf) ;
2373
2374         while (len > 0)
2375         {       if (len < bufferlen)
2376                         bufferlen = (int) len ;
2377                 convert (ptr + total, psf->u.scbuf, bufferlen, psf->norm_double) ;
2378                 writecount = psf_fwrite (psf->u.scbuf, sizeof (signed char), bufferlen, psf) ;
2379                 total += writecount ;
2380                 if (writecount < bufferlen)
2381                         break ;
2382                 len -= writecount ;
2383                 } ;
2384
2385         return total ;
2386 } /* pcm_write_d2sc */
2387
2388 /*==============================================================================
2389 */
2390
2391 static  void
2392 d2uc_array      (const double *src, unsigned char *dest, int count, int normalize)
2393 {       double normfact ;
2394
2395         normfact = normalize ? (1.0 * 0x7F) : 1.0 ;
2396
2397         while (--count >= 0)
2398         {       dest [count] = lrint (src [count] * normfact) + 128 ;
2399                 } ;
2400 } /* d2uc_array */
2401
2402 static  void
2403 d2uc_clip_array (const double *src, unsigned char *dest, int count, int normalize)
2404 {       double  normfact, scaled_value ;
2405
2406         normfact = normalize ? (8.0 * 0x10000000) : (1.0 * 0x1000000) ;
2407
2408         while (--count >= 0)
2409         {       scaled_value = src [count] * normfact ;
2410                 if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
2411                 {       dest [count] = 255 ;
2412                         continue ;
2413                         } ;
2414                 if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
2415                 {       dest [count] = 0 ;
2416                         continue ;
2417                         } ;
2418
2419                 dest [count] = (lrint (src [count] * normfact) >> 24) + 128 ;
2420                 } ;
2421 } /* d2uc_clip_array */
2422
2423 static sf_count_t
2424 pcm_write_d2uc  (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
2425 {       void            (*convert) (const double *, unsigned char *, int, int) ;
2426         int                     bufferlen, writecount ;
2427         sf_count_t      total = 0 ;
2428
2429         convert = (psf->add_clipping) ? d2uc_clip_array : d2uc_array ;
2430         bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
2431
2432         while (len > 0)
2433         {       if (len < bufferlen)
2434                         bufferlen = (int) len ;
2435                 convert (ptr + total, psf->u.ucbuf, bufferlen, psf->norm_double) ;
2436                 writecount = psf_fwrite (psf->u.ucbuf, sizeof (unsigned char), bufferlen, psf) ;
2437                 total += writecount ;
2438                 if (writecount < bufferlen)
2439                         break ;
2440                 len -= writecount ;
2441                 } ;
2442
2443         return total ;
2444 } /* pcm_write_d2uc */
2445
2446 /*==============================================================================
2447 */
2448
2449 static void
2450 d2bes_array (const double *src, short *dest, int count, int normalize)
2451 {       unsigned char   *ucptr ;
2452         short                   value ;
2453         double                  normfact ;
2454
2455         normfact = normalize ? (1.0 * 0x7FFF) : 1.0 ;
2456         ucptr = ((unsigned char*) dest) + 2 * count ;
2457
2458         while (--count >= 0)
2459         {       ucptr -= 2 ;
2460                 value = lrint (src [count] * normfact) ;
2461                 ucptr [1] = value ;
2462                 ucptr [0] = value >> 8 ;
2463                 } ;
2464 } /* d2bes_array */
2465
2466 static void
2467 d2bes_clip_array (const double *src, short *dest, int count, int normalize)
2468 {       unsigned char   *ucptr ;
2469         double                  normfact, scaled_value ;
2470         int                             value ;
2471
2472         normfact = normalize ? (8.0 * 0x10000000) : (1.0 * 0x10000) ;
2473         ucptr = ((unsigned char*) dest) + 2 * count ;
2474
2475         while (--count >= 0)
2476         {       ucptr -= 2 ;
2477                 scaled_value = src [count] * normfact ;
2478                 if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
2479                 {       ucptr [1] = 0xFF ;
2480                         ucptr [0] = 0x7F ;
2481                         continue ;
2482                         } ;
2483                 if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
2484                 {       ucptr [1] = 0x00 ;
2485                         ucptr [0] = 0x80 ;
2486                         continue ;
2487                         } ;
2488
2489                 value = lrint (scaled_value) ;
2490                 ucptr [1] = value >> 16 ;
2491                 ucptr [0] = value >> 24 ;
2492                 } ;
2493 } /* d2bes_clip_array */
2494
2495 static sf_count_t
2496 pcm_write_d2bes (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
2497 {       void            (*convert) (const double *, short *, int, int) ;
2498         int                     bufferlen, writecount ;
2499         sf_count_t      total = 0 ;
2500
2501         convert = (psf->add_clipping) ? d2bes_clip_array : d2bes_array ;
2502         bufferlen = ARRAY_LEN (psf->u.sbuf) ;
2503
2504         while (len > 0)
2505         {       if (len < bufferlen)
2506                         bufferlen = (int) len ;
2507                 convert (ptr + total, psf->u.sbuf, bufferlen, psf->norm_double) ;
2508                 writecount = psf_fwrite (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
2509                 total += writecount ;
2510                 if (writecount < bufferlen)
2511                         break ;
2512                 len -= writecount ;
2513                 } ;
2514
2515         return total ;
2516 } /* pcm_write_d2bes */
2517
2518 /*==============================================================================
2519 */
2520
2521 static void
2522 d2les_array (const double *src, short *dest, int count, int normalize)
2523 {       unsigned char   *ucptr ;
2524         short                   value ;
2525         double                  normfact ;
2526
2527         normfact = normalize ? (1.0 * 0x7FFF) : 1.0 ;
2528         ucptr = ((unsigned char*) dest) + 2 * count ;
2529
2530         while (--count >= 0)
2531         {       ucptr -= 2 ;
2532                 value = lrint (src [count] * normfact) ;
2533                 ucptr [0] = value ;
2534                 ucptr [1] = value >> 8 ;
2535                 } ;
2536 } /* d2les_array */
2537
2538 static void
2539 d2les_clip_array (const double *src, short *dest, int count, int normalize)
2540 {       unsigned char   *ucptr ;
2541         int                             value ;
2542         double                  normfact, scaled_value ;
2543
2544         normfact = normalize ? (8.0 * 0x10000000) : (1.0 * 0x10000) ;
2545         ucptr = ((unsigned char*) dest) + 2 * count ;
2546
2547         while (--count >= 0)
2548         {       ucptr -= 2 ;
2549                 scaled_value = src [count] * normfact ;
2550                 if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
2551                 {       ucptr [0] = 0xFF ;
2552                         ucptr [1] = 0x7F ;
2553                         continue ;
2554                         } ;
2555                 if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
2556                 {       ucptr [0] = 0x00 ;
2557                         ucptr [1] = 0x80 ;
2558                         continue ;
2559                         } ;
2560
2561                 value = lrint (scaled_value) ;
2562                 ucptr [0] = value >> 16 ;
2563                 ucptr [1] = value >> 24 ;
2564                 } ;
2565 } /* d2les_clip_array */
2566
2567 static sf_count_t
2568 pcm_write_d2les (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
2569 {       void            (*convert) (const double *, short *, int, int) ;
2570         int                     bufferlen, writecount ;
2571         sf_count_t      total = 0 ;
2572
2573         convert = (psf->add_clipping) ? d2les_clip_array : d2les_array ;
2574         bufferlen = ARRAY_LEN (psf->u.sbuf) ;
2575
2576         while (len > 0)
2577         {       if (len < bufferlen)
2578                         bufferlen = (int) len ;
2579                 convert (ptr + total, psf->u.sbuf, bufferlen, psf->norm_double) ;
2580                 writecount = psf_fwrite (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
2581                 total += writecount ;
2582                 if (writecount < bufferlen)
2583                         break ;
2584                 len -= writecount ;
2585                 } ;
2586
2587         return total ;
2588 } /* pcm_write_d2les */
2589
2590 /*==============================================================================
2591 */
2592
2593 static void
2594 d2let_array (const double *src, tribyte *dest, int count, int normalize)
2595 {       unsigned char   *ucptr ;
2596         int                             value ;
2597         double                  normfact ;
2598
2599         normfact = normalize ? (1.0 * 0x7FFFFF) : 1.0 ;
2600         ucptr = ((unsigned char*) dest) + 3 * count ;
2601
2602         while (--count >= 0)
2603         {       ucptr -= 3 ;
2604                 value = lrint (src [count] * normfact) ;
2605                 ucptr [0] = value ;
2606                 ucptr [1] = value >> 8 ;
2607                 ucptr [2] = value >> 16 ;
2608                 } ;
2609 } /* d2let_array */
2610
2611 static void
2612 d2let_clip_array (const double *src, tribyte *dest, int count, int normalize)
2613 {       unsigned char   *ucptr ;
2614         int                             value ;
2615         double                  normfact, scaled_value ;
2616
2617         normfact = normalize ? (8.0 * 0x10000000) : (1.0 * 0x100) ;
2618         ucptr = ((unsigned char*) dest) + 3 * count ;
2619
2620         while (--count >= 0)
2621         {       ucptr -= 3 ;
2622                 scaled_value = src [count] * normfact ;
2623                 if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
2624                 {       ucptr [0] = 0xFF ;
2625                         ucptr [1] = 0xFF ;
2626                         ucptr [2] = 0x7F ;
2627                         continue ;
2628                         } ;
2629                 if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
2630                 {       ucptr [0] = 0x00 ;
2631                         ucptr [1] = 0x00 ;
2632                         ucptr [2] = 0x80 ;
2633                         continue ;
2634                         } ;
2635
2636                 value = lrint (scaled_value) ;
2637                 ucptr [0] = value >> 8 ;
2638                 ucptr [1] = value >> 16 ;
2639                 ucptr [2] = value >> 24 ;
2640                 } ;
2641 } /* d2let_clip_array */
2642
2643 static sf_count_t
2644 pcm_write_d2let (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
2645 {       void            (*convert) (const double *, tribyte *, int, int) ;
2646         int                     bufferlen, writecount ;
2647         sf_count_t      total = 0 ;
2648
2649         convert = (psf->add_clipping) ? d2let_clip_array : d2let_array ;
2650         bufferlen = sizeof (psf->u.ucbuf) / SIZEOF_TRIBYTE ;
2651
2652         while (len > 0)
2653         {       if (len < bufferlen)
2654                         bufferlen = (int) len ;
2655                 convert (ptr + total, (tribyte*) (psf->u.ucbuf), bufferlen, psf->norm_double) ;
2656                 writecount = psf_fwrite (psf->u.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
2657                 total += writecount ;
2658                 if (writecount < bufferlen)
2659                         break ;
2660                 len -= writecount ;
2661                 } ;
2662
2663         return total ;
2664 } /* pcm_write_d2let */
2665
2666 /*==============================================================================
2667 */
2668
2669 static void
2670 d2bet_array (const double *src, tribyte *dest, int count, int normalize)
2671 {       unsigned char   *ucptr ;
2672         int                             value ;
2673         double                  normfact ;
2674
2675         normfact = normalize ? (1.0 * 0x7FFFFF) : 1.0 ;
2676         ucptr = ((unsigned char*) dest) + 3 * count ;
2677
2678         while (--count >= 0)
2679         {       ucptr -= 3 ;
2680                 value = lrint (src [count] * normfact) ;
2681                 ucptr [2] = value ;
2682                 ucptr [1] = value >> 8 ;
2683                 ucptr [0] = value >> 16 ;
2684                 } ;
2685 } /* d2bet_array */
2686
2687 static void
2688 d2bet_clip_array (const double *src, tribyte *dest, int count, int normalize)
2689 {       unsigned char   *ucptr ;
2690         int                             value ;
2691         double                  normfact, scaled_value ;
2692
2693         normfact = normalize ? (8.0 * 0x10000000) : (1.0 * 0x100) ;
2694         ucptr = ((unsigned char*) dest) + 3 * count ;
2695
2696         while (--count >= 0)
2697         {       ucptr -= 3 ;
2698                 scaled_value = src [count] * normfact ;
2699                 if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
2700                 {       ucptr [2] = 0xFF ;
2701                         ucptr [1] = 0xFF ;
2702                         ucptr [0] = 0x7F ;
2703                         continue ;
2704                         } ;
2705                 if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
2706                 {       ucptr [2] = 0x00 ;
2707                         ucptr [1] = 0x00 ;
2708                         ucptr [0] = 0x80 ;
2709                         continue ;
2710                         } ;
2711
2712                 value = lrint (scaled_value) ;
2713                 ucptr [2] = value >> 8 ;
2714                 ucptr [1] = value >> 16 ;
2715                 ucptr [0] = value >> 24 ;
2716                 } ;
2717 } /* d2bet_clip_array */
2718
2719 static sf_count_t
2720 pcm_write_d2bet (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
2721 {       void            (*convert) (const double *, tribyte *, int, int) ;
2722         int                     bufferlen, writecount ;
2723         sf_count_t      total = 0 ;
2724
2725         convert = (psf->add_clipping) ? d2bet_clip_array : d2bet_array ;
2726         bufferlen = sizeof (psf->u.ucbuf) / SIZEOF_TRIBYTE ;
2727
2728         while (len > 0)
2729         {       if (len < bufferlen)
2730                         bufferlen = (int) len ;
2731                 convert (ptr + total, (tribyte*) (psf->u.ucbuf), bufferlen, psf->norm_double) ;
2732                 writecount = psf_fwrite (psf->u.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
2733                 total += writecount ;
2734                 if (writecount < bufferlen)
2735                         break ;
2736                 len -= writecount ;
2737                 } ;
2738
2739         return total ;
2740 } /* pcm_write_d2bet */
2741
2742 /*==============================================================================
2743 */
2744
2745 static void
2746 d2bei_array (const double *src, int *dest, int count, int normalize)
2747 {       unsigned char   *ucptr ;
2748         int                             value ;
2749         double                  normfact ;
2750
2751         normfact = normalize ? (1.0 * 0x7FFFFFFF) : 1.0 ;
2752         ucptr = ((unsigned char*) dest) + 4 * count ;
2753
2754         while (--count >= 0)
2755         {       ucptr -= 4 ;
2756                 value = lrint (src [count] * normfact) ;
2757                 ucptr [0] = value >> 24 ;
2758                 ucptr [1] = value >> 16 ;
2759                 ucptr [2] = value >> 8 ;
2760                 ucptr [3] = value ;
2761                 } ;
2762 } /* d2bei_array */
2763
2764 static void
2765 d2bei_clip_array (const double *src, int *dest, int count, int normalize)
2766 {       unsigned char   *ucptr ;
2767         int                             value ;
2768         double                  normfact, scaled_value ;
2769
2770         normfact = normalize ? (8.0 * 0x10000000) : 1.0 ;
2771         ucptr = ((unsigned char*) dest) + 4 * count ;
2772
2773         while (--count >= 0)
2774         {       ucptr -= 4 ;
2775                 scaled_value = src [count] * normfact ;
2776                 if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
2777                 {       ucptr [3] = 0xFF ;
2778                         ucptr [2] = 0xFF ;
2779                         ucptr [1] = 0xFF ;
2780                         ucptr [0] = 0x7F ;
2781                         continue ;
2782                         } ;
2783                 if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
2784                 {       ucptr [3] = 0x00 ;
2785                         ucptr [2] = 0x00 ;
2786                         ucptr [1] = 0x00 ;
2787                         ucptr [0] = 0x80 ;
2788                         continue ;
2789                         } ;
2790
2791                 value = lrint (scaled_value) ;
2792                 ucptr [0] = value >> 24 ;
2793                 ucptr [1] = value >> 16 ;
2794                 ucptr [2] = value >> 8 ;
2795                 ucptr [3] = value ;
2796                 } ;
2797 } /* d2bei_clip_array */
2798
2799 static sf_count_t
2800 pcm_write_d2bei (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
2801 {       void            (*convert) (const double *, int *, int, int) ;
2802         int                     bufferlen, writecount ;
2803         sf_count_t      total = 0 ;
2804
2805         convert = (psf->add_clipping) ? d2bei_clip_array : d2bei_array ;
2806         bufferlen = ARRAY_LEN (psf->u.ibuf) ;
2807
2808         while (len > 0)
2809         {       if (len < bufferlen)
2810                         bufferlen = (int) len ;
2811                 convert (ptr + total, psf->u.ibuf, bufferlen, psf->norm_double) ;
2812                 writecount = psf_fwrite (psf->u.ibuf, sizeof (int), bufferlen, psf) ;
2813                 total += writecount ;
2814                 if (writecount < bufferlen)
2815                         break ;
2816                 len -= writecount ;
2817                 } ;
2818
2819         return total ;
2820 } /* pcm_write_d2bei */
2821
2822 /*==============================================================================
2823 */
2824
2825 static void
2826 d2lei_array (const double *src, int *dest, int count, int normalize)
2827 {       unsigned char   *ucptr ;
2828         int                             value ;
2829         double                  normfact ;
2830
2831         normfact = normalize ? (1.0 * 0x7FFFFFFF) : 1.0 ;
2832         ucptr = ((unsigned char*) dest) + 4 * count ;
2833
2834         while (--count >= 0)
2835         {       ucptr -= 4 ;
2836                 value = lrint (src [count] * normfact) ;
2837                 ucptr [0] = value ;
2838                 ucptr [1] = value >> 8 ;
2839                 ucptr [2] = value >> 16 ;
2840                 ucptr [3] = value >> 24 ;
2841                 } ;
2842 } /* d2lei_array */
2843
2844 static void
2845 d2lei_clip_array (const double *src, int *dest, int count, int normalize)
2846 {       unsigned char   *ucptr ;
2847         int                             value ;
2848         double                  normfact, scaled_value ;
2849
2850         normfact = normalize ? (8.0 * 0x10000000) : 1.0 ;
2851         ucptr = ((unsigned char*) dest) + 4 * count ;
2852
2853         while (--count >= 0)
2854         {       ucptr -= 4 ;
2855                 scaled_value = src [count] * normfact ;
2856                 if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
2857                 {       ucptr [0] = 0xFF ;
2858                         ucptr [1] = 0xFF ;
2859                         ucptr [2] = 0xFF ;
2860                         ucptr [3] = 0x7F ;
2861                         continue ;
2862                         } ;
2863                 if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
2864                 {       ucptr [0] = 0x00 ;
2865                         ucptr [1] = 0x00 ;
2866                         ucptr [2] = 0x00 ;
2867                         ucptr [3] = 0x80 ;
2868                         continue ;
2869                         } ;
2870
2871                 value = lrint (scaled_value) ;
2872                 ucptr [0] = value ;
2873                 ucptr [1] = value >> 8 ;
2874                 ucptr [2] = value >> 16 ;
2875                 ucptr [3] = value >> 24 ;
2876                 } ;
2877 } /* d2lei_clip_array */
2878
2879 static sf_count_t
2880 pcm_write_d2lei (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
2881 {       void            (*convert) (const double *, int *, int, int) ;
2882         int                     bufferlen, writecount ;
2883         sf_count_t      total = 0 ;
2884
2885         convert = (psf->add_clipping) ? d2lei_clip_array : d2lei_array ;
2886         bufferlen = ARRAY_LEN (psf->u.ibuf) ;
2887
2888         while (len > 0)
2889         {       if (len < bufferlen)
2890                         bufferlen = (int) len ;
2891                 convert (ptr + total, psf->u.ibuf, bufferlen, psf->norm_double) ;
2892                 writecount = psf_fwrite (psf->u.ibuf, sizeof (int), bufferlen, psf) ;
2893                 total += writecount ;
2894                 if (writecount < bufferlen)
2895                         break ;
2896                 len -= writecount ;
2897                 } ;
2898
2899         return total ;
2900 } /* pcm_write_d2lei */
2901