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