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