/project/jni/sndfile/src/double64.c

https://github.com/aichunyu/FFPlayer · C · 1043 lines · 739 code · 231 blank · 73 comment · 189 complexity · 69f0320336875b94132888e6bb8e639d MD5 · raw file

  1. /*
  2. ** Copyright (C) 1999-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
  3. **
  4. ** This program is free software; you can redistribute it and/or modify
  5. ** it under the terms of the GNU Lesser General Public License as published by
  6. ** the Free Software Foundation; either version 2.1 of the License, or
  7. ** (at your option) any later version.
  8. **
  9. ** This program is distributed in the hope that it will be useful,
  10. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. ** GNU Lesser General Public License for more details.
  13. **
  14. ** You should have received a copy of the GNU Lesser General Public License
  15. ** along with this program; if not, write to the Free Software
  16. ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17. */
  18. #include "sfconfig.h"
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <limits.h>
  23. #include <math.h>
  24. #include "sndfile.h"
  25. #include "sfendian.h"
  26. #include "common.h"
  27. #if CPU_IS_LITTLE_ENDIAN
  28. #define DOUBLE64_READ double64_le_read
  29. #define DOUBLE64_WRITE double64_le_write
  30. #elif CPU_IS_BIG_ENDIAN
  31. #define DOUBLE64_READ double64_be_read
  32. #define DOUBLE64_WRITE double64_be_write
  33. #endif
  34. /* A 32 number which will not overflow when multiplied by sizeof (double). */
  35. #define SENSIBLE_LEN (0x8000000)
  36. /*--------------------------------------------------------------------------------------------
  37. ** Processor floating point capabilities. double64_get_capability () returns one of the
  38. ** latter three values.
  39. */
  40. enum
  41. { DOUBLE_UNKNOWN = 0x00,
  42. DOUBLE_CAN_RW_LE = 0x23,
  43. DOUBLE_CAN_RW_BE = 0x34,
  44. DOUBLE_BROKEN_LE = 0x45,
  45. DOUBLE_BROKEN_BE = 0x56
  46. } ;
  47. /*--------------------------------------------------------------------------------------------
  48. ** Prototypes for private functions.
  49. */
  50. static sf_count_t host_read_d2s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
  51. static sf_count_t host_read_d2i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
  52. static sf_count_t host_read_d2f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
  53. static sf_count_t host_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
  54. static sf_count_t host_write_s2d (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
  55. static sf_count_t host_write_i2d (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
  56. static sf_count_t host_write_f2d (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
  57. static sf_count_t host_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
  58. static void double64_peak_update (SF_PRIVATE *psf, const double *buffer, int count, sf_count_t indx) ;
  59. static int double64_get_capability (SF_PRIVATE *psf) ;
  60. static sf_count_t replace_read_d2s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
  61. static sf_count_t replace_read_d2i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
  62. static sf_count_t replace_read_d2f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
  63. static sf_count_t replace_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
  64. static sf_count_t replace_write_s2d (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
  65. static sf_count_t replace_write_i2d (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
  66. static sf_count_t replace_write_f2d (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
  67. static sf_count_t replace_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
  68. static void d2bd_read (double *buffer, int count) ;
  69. static void bd2d_write (double *buffer, int count) ;
  70. /*--------------------------------------------------------------------------------------------
  71. ** Exported functions.
  72. */
  73. int
  74. double64_init (SF_PRIVATE *psf)
  75. { static int double64_caps ;
  76. double64_caps = double64_get_capability (psf) ;
  77. psf->blockwidth = sizeof (double) * psf->sf.channels ;
  78. if (psf->file.mode == SFM_READ || psf->file.mode == SFM_RDWR)
  79. { switch (psf->endian + double64_caps)
  80. { case (SF_ENDIAN_BIG + DOUBLE_CAN_RW_BE) :
  81. psf->data_endswap = SF_FALSE ;
  82. psf->read_short = host_read_d2s ;
  83. psf->read_int = host_read_d2i ;
  84. psf->read_float = host_read_d2f ;
  85. psf->read_double = host_read_d ;
  86. break ;
  87. case (SF_ENDIAN_LITTLE + DOUBLE_CAN_RW_LE) :
  88. psf->data_endswap = SF_FALSE ;
  89. psf->read_short = host_read_d2s ;
  90. psf->read_int = host_read_d2i ;
  91. psf->read_float = host_read_d2f ;
  92. psf->read_double = host_read_d ;
  93. break ;
  94. case (SF_ENDIAN_BIG + DOUBLE_CAN_RW_LE) :
  95. psf->data_endswap = SF_TRUE ;
  96. psf->read_short = host_read_d2s ;
  97. psf->read_int = host_read_d2i ;
  98. psf->read_float = host_read_d2f ;
  99. psf->read_double = host_read_d ;
  100. break ;
  101. case (SF_ENDIAN_LITTLE + DOUBLE_CAN_RW_BE) :
  102. psf->data_endswap = SF_TRUE ;
  103. psf->read_short = host_read_d2s ;
  104. psf->read_int = host_read_d2i ;
  105. psf->read_float = host_read_d2f ;
  106. psf->read_double = host_read_d ;
  107. break ;
  108. /* When the CPU is not IEEE compatible. */
  109. case (SF_ENDIAN_BIG + DOUBLE_BROKEN_BE) :
  110. psf->data_endswap = SF_FALSE ;
  111. psf->read_short = replace_read_d2s ;
  112. psf->read_int = replace_read_d2i ;
  113. psf->read_float = replace_read_d2f ;
  114. psf->read_double = replace_read_d ;
  115. break ;
  116. case (SF_ENDIAN_LITTLE + DOUBLE_BROKEN_LE) :
  117. psf->data_endswap = SF_FALSE ;
  118. psf->read_short = replace_read_d2s ;
  119. psf->read_int = replace_read_d2i ;
  120. psf->read_float = replace_read_d2f ;
  121. psf->read_double = replace_read_d ;
  122. break ;
  123. case (SF_ENDIAN_BIG + DOUBLE_BROKEN_LE) :
  124. psf->data_endswap = SF_TRUE ;
  125. psf->read_short = replace_read_d2s ;
  126. psf->read_int = replace_read_d2i ;
  127. psf->read_float = replace_read_d2f ;
  128. psf->read_double = replace_read_d ;
  129. break ;
  130. case (SF_ENDIAN_LITTLE + DOUBLE_BROKEN_BE) :
  131. psf->data_endswap = SF_TRUE ;
  132. psf->read_short = replace_read_d2s ;
  133. psf->read_int = replace_read_d2i ;
  134. psf->read_float = replace_read_d2f ;
  135. psf->read_double = replace_read_d ;
  136. break ;
  137. default : break ;
  138. } ;
  139. } ;
  140. if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
  141. { switch (psf->endian + double64_caps)
  142. { case (SF_ENDIAN_LITTLE + DOUBLE_CAN_RW_LE) :
  143. psf->data_endswap = SF_FALSE ;
  144. psf->write_short = host_write_s2d ;
  145. psf->write_int = host_write_i2d ;
  146. psf->write_float = host_write_f2d ;
  147. psf->write_double = host_write_d ;
  148. break ;
  149. case (SF_ENDIAN_BIG + DOUBLE_CAN_RW_BE) :
  150. psf->data_endswap = SF_FALSE ;
  151. psf->write_short = host_write_s2d ;
  152. psf->write_int = host_write_i2d ;
  153. psf->write_float = host_write_f2d ;
  154. psf->write_double = host_write_d ;
  155. break ;
  156. case (SF_ENDIAN_BIG + DOUBLE_CAN_RW_LE) :
  157. psf->data_endswap = SF_TRUE ;
  158. psf->write_short = host_write_s2d ;
  159. psf->write_int = host_write_i2d ;
  160. psf->write_float = host_write_f2d ;
  161. psf->write_double = host_write_d ;
  162. break ;
  163. case (SF_ENDIAN_LITTLE + DOUBLE_CAN_RW_BE) :
  164. psf->data_endswap = SF_TRUE ;
  165. psf->write_short = host_write_s2d ;
  166. psf->write_int = host_write_i2d ;
  167. psf->write_float = host_write_f2d ;
  168. psf->write_double = host_write_d ;
  169. break ;
  170. /* When the CPU is not IEEE compatible. */
  171. case (SF_ENDIAN_LITTLE + DOUBLE_BROKEN_LE) :
  172. psf->data_endswap = SF_FALSE ;
  173. psf->write_short = replace_write_s2d ;
  174. psf->write_int = replace_write_i2d ;
  175. psf->write_float = replace_write_f2d ;
  176. psf->write_double = replace_write_d ;
  177. break ;
  178. case (SF_ENDIAN_BIG + DOUBLE_BROKEN_BE) :
  179. psf->data_endswap = SF_FALSE ;
  180. psf->write_short = replace_write_s2d ;
  181. psf->write_int = replace_write_i2d ;
  182. psf->write_float = replace_write_f2d ;
  183. psf->write_double = replace_write_d ;
  184. break ;
  185. case (SF_ENDIAN_BIG + DOUBLE_BROKEN_LE) :
  186. psf->data_endswap = SF_TRUE ;
  187. psf->write_short = replace_write_s2d ;
  188. psf->write_int = replace_write_i2d ;
  189. psf->write_float = replace_write_f2d ;
  190. psf->write_double = replace_write_d ;
  191. break ;
  192. case (SF_ENDIAN_LITTLE + DOUBLE_BROKEN_BE) :
  193. psf->data_endswap = SF_TRUE ;
  194. psf->write_short = replace_write_s2d ;
  195. psf->write_int = replace_write_i2d ;
  196. psf->write_float = replace_write_f2d ;
  197. psf->write_double = replace_write_d ;
  198. break ;
  199. default : break ;
  200. } ;
  201. } ;
  202. if (psf->filelength > psf->dataoffset)
  203. { psf->datalength = (psf->dataend > 0) ? psf->dataend - psf->dataoffset :
  204. psf->filelength - psf->dataoffset ;
  205. }
  206. else
  207. psf->datalength = 0 ;
  208. psf->sf.frames = psf->datalength / psf->blockwidth ;
  209. return 0 ;
  210. } /* double64_init */
  211. /*----------------------------------------------------------------------------
  212. ** From : http://www.hpcf.cam.ac.uk/fp_formats.html
  213. **
  214. ** 64 bit double precision layout (big endian)
  215. ** Sign bit 0
  216. ** Exponent bits 1-11
  217. ** Mantissa bits 12-63
  218. ** Exponent Offset 1023
  219. **
  220. ** double single
  221. **
  222. ** +INF 7FF0000000000000 7F800000
  223. ** -INF FFF0000000000000 FF800000
  224. ** NaN 7FF0000000000001 7F800001
  225. ** to to
  226. ** 7FFFFFFFFFFFFFFF 7FFFFFFF
  227. ** and and
  228. ** FFF0000000000001 FF800001
  229. ** to to
  230. ** FFFFFFFFFFFFFFFF FFFFFFFF
  231. ** +OVER 7FEFFFFFFFFFFFFF 7F7FFFFF
  232. ** -OVER FFEFFFFFFFFFFFFF FF7FFFFF
  233. ** +UNDER 0010000000000000 00800000
  234. ** -UNDER 8010000000000000 80800000
  235. */
  236. double
  237. double64_be_read (unsigned char *cptr)
  238. { int exponent, negative, upper, lower ;
  239. double dvalue ;
  240. negative = (cptr [0] & 0x80) ? 1 : 0 ;
  241. exponent = ((cptr [0] & 0x7F) << 4) | ((cptr [1] >> 4) & 0xF) ;
  242. /* Might not have a 64 bit long, so load the mantissa into a double. */
  243. upper = (((cptr [1] & 0xF) << 24) | (cptr [2] << 16) | (cptr [3] << 8) | cptr [4]) ;
  244. lower = (cptr [5] << 16) | (cptr [6] << 8) | cptr [7] ;
  245. if (exponent == 0 && upper == 0 && lower == 0)
  246. return 0.0 ;
  247. dvalue = upper + lower / ((double) 0x1000000) ;
  248. dvalue += 0x10000000 ;
  249. exponent = exponent - 0x3FF ;
  250. dvalue = dvalue / ((double) 0x10000000) ;
  251. if (negative)
  252. dvalue *= -1 ;
  253. if (exponent > 0)
  254. dvalue *= pow (2.0, exponent) ;
  255. else if (exponent < 0)
  256. dvalue /= pow (2.0, abs (exponent)) ;
  257. return dvalue ;
  258. } /* double64_be_read */
  259. double
  260. double64_le_read (unsigned char *cptr)
  261. { int exponent, negative, upper, lower ;
  262. double dvalue ;
  263. negative = (cptr [7] & 0x80) ? 1 : 0 ;
  264. exponent = ((cptr [7] & 0x7F) << 4) | ((cptr [6] >> 4) & 0xF) ;
  265. /* Might not have a 64 bit long, so load the mantissa into a double. */
  266. upper = ((cptr [6] & 0xF) << 24) | (cptr [5] << 16) | (cptr [4] << 8) | cptr [3] ;
  267. lower = (cptr [2] << 16) | (cptr [1] << 8) | cptr [0] ;
  268. if (exponent == 0 && upper == 0 && lower == 0)
  269. return 0.0 ;
  270. dvalue = upper + lower / ((double) 0x1000000) ;
  271. dvalue += 0x10000000 ;
  272. exponent = exponent - 0x3FF ;
  273. dvalue = dvalue / ((double) 0x10000000) ;
  274. if (negative)
  275. dvalue *= -1 ;
  276. if (exponent > 0)
  277. dvalue *= pow (2.0, exponent) ;
  278. else if (exponent < 0)
  279. dvalue /= pow (2.0, abs (exponent)) ;
  280. return dvalue ;
  281. } /* double64_le_read */
  282. void
  283. double64_be_write (double in, unsigned char *out)
  284. { int exponent, mantissa ;
  285. memset (out, 0, sizeof (double)) ;
  286. if (fabs (in) < 1e-30)
  287. return ;
  288. if (in < 0.0)
  289. { in *= -1.0 ;
  290. out [0] |= 0x80 ;
  291. } ;
  292. in = frexp (in, &exponent) ;
  293. exponent += 1022 ;
  294. out [0] |= (exponent >> 4) & 0x7F ;
  295. out [1] |= (exponent << 4) & 0xF0 ;
  296. in *= 0x20000000 ;
  297. mantissa = lrint (floor (in)) ;
  298. out [1] |= (mantissa >> 24) & 0xF ;
  299. out [2] = (mantissa >> 16) & 0xFF ;
  300. out [3] = (mantissa >> 8) & 0xFF ;
  301. out [4] = mantissa & 0xFF ;
  302. in = fmod (in, 1.0) ;
  303. in *= 0x1000000 ;
  304. mantissa = lrint (floor (in)) ;
  305. out [5] = (mantissa >> 16) & 0xFF ;
  306. out [6] = (mantissa >> 8) & 0xFF ;
  307. out [7] = mantissa & 0xFF ;
  308. return ;
  309. } /* double64_be_write */
  310. void
  311. double64_le_write (double in, unsigned char *out)
  312. { int exponent, mantissa ;
  313. memset (out, 0, sizeof (double)) ;
  314. if (fabs (in) < 1e-30)
  315. return ;
  316. if (in < 0.0)
  317. { in *= -1.0 ;
  318. out [7] |= 0x80 ;
  319. } ;
  320. in = frexp (in, &exponent) ;
  321. exponent += 1022 ;
  322. out [7] |= (exponent >> 4) & 0x7F ;
  323. out [6] |= (exponent << 4) & 0xF0 ;
  324. in *= 0x20000000 ;
  325. mantissa = lrint (floor (in)) ;
  326. out [6] |= (mantissa >> 24) & 0xF ;
  327. out [5] = (mantissa >> 16) & 0xFF ;
  328. out [4] = (mantissa >> 8) & 0xFF ;
  329. out [3] = mantissa & 0xFF ;
  330. in = fmod (in, 1.0) ;
  331. in *= 0x1000000 ;
  332. mantissa = lrint (floor (in)) ;
  333. out [2] = (mantissa >> 16) & 0xFF ;
  334. out [1] = (mantissa >> 8) & 0xFF ;
  335. out [0] = mantissa & 0xFF ;
  336. return ;
  337. } /* double64_le_write */
  338. /*==============================================================================================
  339. ** Private functions.
  340. */
  341. static void
  342. double64_peak_update (SF_PRIVATE *psf, const double *buffer, int count, sf_count_t indx)
  343. { int chan ;
  344. int k, position ;
  345. float fmaxval ;
  346. for (chan = 0 ; chan < psf->sf.channels ; chan++)
  347. { fmaxval = fabs (buffer [chan]) ;
  348. position = 0 ;
  349. for (k = chan ; k < count ; k += psf->sf.channels)
  350. if (fmaxval < fabs (buffer [k]))
  351. { fmaxval = fabs (buffer [k]) ;
  352. position = k ;
  353. } ;
  354. if (fmaxval > psf->peak_info->peaks [chan].value)
  355. { psf->peak_info->peaks [chan].value = fmaxval ;
  356. psf->peak_info->peaks [chan].position = psf->write_current + indx + (position / psf->sf.channels) ;
  357. } ;
  358. } ;
  359. return ;
  360. } /* double64_peak_update */
  361. static int
  362. double64_get_capability (SF_PRIVATE *psf)
  363. { union
  364. { double d ;
  365. unsigned char c [8] ;
  366. } data ;
  367. data.d = 1.234567890123456789 ; /* Some abitrary value. */
  368. if (! psf->ieee_replace)
  369. { /* If this test is true ints and floats are compatible and little endian. */
  370. if (data.c [0] == 0xfb && data.c [1] == 0x59 && data.c [2] == 0x8c && data.c [3] == 0x42 &&
  371. data.c [4] == 0xca && data.c [5] == 0xc0 && data.c [6] == 0xf3 && data.c [7] == 0x3f)
  372. return DOUBLE_CAN_RW_LE ;
  373. /* If this test is true ints and floats are compatible and big endian. */
  374. if (data.c [0] == 0x3f && data.c [1] == 0xf3 && data.c [2] == 0xc0 && data.c [3] == 0xca &&
  375. data.c [4] == 0x42 && data.c [5] == 0x8c && data.c [6] == 0x59 && data.c [7] == 0xfb)
  376. return DOUBLE_CAN_RW_BE ;
  377. } ;
  378. /* Doubles are broken. Don't expect reading or writing to be fast. */
  379. psf_log_printf (psf, "Using IEEE replacement code for double.\n") ;
  380. return (CPU_IS_LITTLE_ENDIAN) ? DOUBLE_BROKEN_LE : DOUBLE_BROKEN_BE ;
  381. } /* double64_get_capability */
  382. /*=======================================================================================
  383. */
  384. static void
  385. d2s_array (const double *src, int count, short *dest, double scale)
  386. { while (--count >= 0)
  387. { dest [count] = lrint (scale * src [count]) ;
  388. } ;
  389. } /* d2s_array */
  390. static void
  391. d2s_clip_array (const double *src, int count, short *dest, double scale)
  392. { while (--count >= 0)
  393. { double tmp = scale * src [count] ;
  394. if (CPU_CLIPS_POSITIVE == 0 && tmp > 32767.0)
  395. dest [count] = SHRT_MAX ;
  396. else if (CPU_CLIPS_NEGATIVE == 0 && tmp < -32768.0)
  397. dest [count] = SHRT_MIN ;
  398. else
  399. dest [count] = lrint (tmp) ;
  400. } ;
  401. } /* d2s_clip_array */
  402. static void
  403. d2i_array (const double *src, int count, int *dest, double scale)
  404. { while (--count >= 0)
  405. { dest [count] = lrint (scale * src [count]) ;
  406. } ;
  407. } /* d2i_array */
  408. static void
  409. d2i_clip_array (const double *src, int count, int *dest, double scale)
  410. { while (--count >= 0)
  411. { float tmp = scale * src [count] ;
  412. if (CPU_CLIPS_POSITIVE == 0 && tmp > (1.0 * INT_MAX))
  413. dest [count] = INT_MAX ;
  414. else if (CPU_CLIPS_NEGATIVE == 0 && tmp < (-1.0 * INT_MAX))
  415. dest [count] = INT_MIN ;
  416. else
  417. dest [count] = lrint (tmp) ;
  418. } ;
  419. } /* d2i_clip_array */
  420. static inline void
  421. d2f_array (const double *src, int count, float *dest)
  422. { while (--count >= 0)
  423. { dest [count] = src [count] ;
  424. } ;
  425. } /* d2f_array */
  426. static inline void
  427. s2d_array (const short *src, double *dest, int count, double scale)
  428. { while (--count >= 0)
  429. { dest [count] = scale * src [count] ;
  430. } ;
  431. } /* s2d_array */
  432. static inline void
  433. i2d_array (const int *src, double *dest, int count, double scale)
  434. { while (--count >= 0)
  435. { dest [count] = scale * src [count] ;
  436. } ;
  437. } /* i2d_array */
  438. static inline void
  439. f2d_array (const float *src, double *dest, int count)
  440. { while (--count >= 0)
  441. { dest [count] = src [count] ;
  442. } ;
  443. } /* f2d_array */
  444. /*----------------------------------------------------------------------------------------------
  445. */
  446. static sf_count_t
  447. host_read_d2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
  448. { void (*convert) (const double *, int, short *, double) ;
  449. int bufferlen, readcount ;
  450. sf_count_t total = 0 ;
  451. double scale ;
  452. convert = (psf->add_clipping) ? d2s_clip_array : d2s_array ;
  453. bufferlen = ARRAY_LEN (psf->u.dbuf) ;
  454. scale = (psf->float_int_mult == 0) ? 1.0 : 0x7FFF / psf->float_max ;
  455. while (len > 0)
  456. { if (len < bufferlen)
  457. bufferlen = (int) len ;
  458. readcount = psf_fread (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
  459. if (psf->data_endswap == SF_TRUE)
  460. endswap_double_array (psf->u.dbuf, readcount) ;
  461. convert (psf->u.dbuf, readcount, ptr + total, scale) ;
  462. total += readcount ;
  463. len -= readcount ;
  464. if (readcount < bufferlen)
  465. break ;
  466. } ;
  467. return total ;
  468. } /* host_read_d2s */
  469. static sf_count_t
  470. host_read_d2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
  471. { void (*convert) (const double *, int, int *, double) ;
  472. int bufferlen, readcount ;
  473. sf_count_t total = 0 ;
  474. double scale ;
  475. convert = (psf->add_clipping) ? d2i_clip_array : d2i_array ;
  476. bufferlen = ARRAY_LEN (psf->u.dbuf) ;
  477. scale = (psf->float_int_mult == 0) ? 1.0 : 0x7FFFFFFF / psf->float_max ;
  478. while (len > 0)
  479. { if (len < bufferlen)
  480. bufferlen = (int) len ;
  481. readcount = psf_fread (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
  482. if (psf->data_endswap == SF_TRUE)
  483. endswap_double_array (psf->u.dbuf, bufferlen) ;
  484. convert (psf->u.dbuf, readcount, ptr + total, scale) ;
  485. total += readcount ;
  486. len -= readcount ;
  487. if (readcount < bufferlen)
  488. break ;
  489. } ;
  490. return total ;
  491. } /* host_read_d2i */
  492. static sf_count_t
  493. host_read_d2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
  494. { int bufferlen, readcount ;
  495. sf_count_t total = 0 ;
  496. bufferlen = ARRAY_LEN (psf->u.dbuf) ;
  497. while (len > 0)
  498. { if (len < bufferlen)
  499. bufferlen = (int) len ;
  500. readcount = psf_fread (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
  501. if (psf->data_endswap == SF_TRUE)
  502. endswap_double_array (psf->u.dbuf, bufferlen) ;
  503. d2f_array (psf->u.dbuf, readcount, ptr + total) ;
  504. total += readcount ;
  505. len -= readcount ;
  506. if (readcount < bufferlen)
  507. break ;
  508. } ;
  509. return total ;
  510. } /* host_read_d2f */
  511. static sf_count_t
  512. host_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
  513. { int bufferlen ;
  514. sf_count_t readcount, total = 0 ;
  515. readcount = psf_fread (ptr, sizeof (double), len, psf) ;
  516. if (psf->data_endswap != SF_TRUE)
  517. return readcount ;
  518. /* If the read length was sensible, endswap output in one go. */
  519. if (readcount < SENSIBLE_LEN)
  520. { endswap_double_array (ptr, readcount) ;
  521. return readcount ;
  522. } ;
  523. bufferlen = SENSIBLE_LEN ;
  524. while (len > 0)
  525. { if (len < bufferlen)
  526. bufferlen = (int) len ;
  527. endswap_double_array (ptr + total, bufferlen) ;
  528. total += bufferlen ;
  529. len -= bufferlen ;
  530. } ;
  531. return total ;
  532. } /* host_read_d */
  533. static sf_count_t
  534. host_write_s2d (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
  535. { int bufferlen, writecount ;
  536. sf_count_t total = 0 ;
  537. double scale ;
  538. scale = (psf->scale_int_float == 0) ? 1.0 : 1.0 / 0x8000 ;
  539. bufferlen = ARRAY_LEN (psf->u.dbuf) ;
  540. while (len > 0)
  541. { if (len < bufferlen)
  542. bufferlen = (int) len ;
  543. s2d_array (ptr + total, psf->u.dbuf, bufferlen, scale) ;
  544. if (psf->peak_info)
  545. double64_peak_update (psf, psf->u.dbuf, bufferlen, total / psf->sf.channels) ;
  546. if (psf->data_endswap == SF_TRUE)
  547. endswap_double_array (psf->u.dbuf, bufferlen) ;
  548. writecount = psf_fwrite (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
  549. total += writecount ;
  550. if (writecount < bufferlen)
  551. break ;
  552. len -= writecount ;
  553. } ;
  554. return total ;
  555. } /* host_write_s2d */
  556. static sf_count_t
  557. host_write_i2d (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
  558. { int bufferlen, writecount ;
  559. sf_count_t total = 0 ;
  560. double scale ;
  561. scale = (psf->scale_int_float == 0) ? 1.0 : 1.0 / (8.0 * 0x10000000) ;
  562. bufferlen = ARRAY_LEN (psf->u.dbuf) ;
  563. while (len > 0)
  564. { if (len < bufferlen)
  565. bufferlen = (int) len ;
  566. i2d_array (ptr + total, psf->u.dbuf, bufferlen, scale) ;
  567. if (psf->peak_info)
  568. double64_peak_update (psf, psf->u.dbuf, bufferlen, total / psf->sf.channels) ;
  569. if (psf->data_endswap == SF_TRUE)
  570. endswap_double_array (psf->u.dbuf, bufferlen) ;
  571. writecount = psf_fwrite (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
  572. total += writecount ;
  573. if (writecount < bufferlen)
  574. break ;
  575. len -= writecount ;
  576. } ;
  577. return total ;
  578. } /* host_write_i2d */
  579. static sf_count_t
  580. host_write_f2d (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
  581. { int bufferlen, writecount ;
  582. sf_count_t total = 0 ;
  583. bufferlen = ARRAY_LEN (psf->u.dbuf) ;
  584. while (len > 0)
  585. { if (len < bufferlen)
  586. bufferlen = (int) len ;
  587. f2d_array (ptr + total, psf->u.dbuf, bufferlen) ;
  588. if (psf->peak_info)
  589. double64_peak_update (psf, psf->u.dbuf, bufferlen, total / psf->sf.channels) ;
  590. if (psf->data_endswap == SF_TRUE)
  591. endswap_double_array (psf->u.dbuf, bufferlen) ;
  592. writecount = psf_fwrite (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
  593. total += writecount ;
  594. if (writecount < bufferlen)
  595. break ;
  596. len -= writecount ;
  597. } ;
  598. return total ;
  599. } /* host_write_f2d */
  600. static sf_count_t
  601. host_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
  602. { int bufferlen, writecount ;
  603. sf_count_t total = 0 ;
  604. if (psf->peak_info)
  605. double64_peak_update (psf, ptr, len, 0) ;
  606. if (psf->data_endswap != SF_TRUE)
  607. return psf_fwrite (ptr, sizeof (double), len, psf) ;
  608. bufferlen = ARRAY_LEN (psf->u.dbuf) ;
  609. while (len > 0)
  610. { if (len < bufferlen)
  611. bufferlen = (int) len ;
  612. endswap_double_copy (psf->u.dbuf, ptr + total, bufferlen) ;
  613. writecount = psf_fwrite (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
  614. total += writecount ;
  615. if (writecount < bufferlen)
  616. break ;
  617. len -= writecount ;
  618. } ;
  619. return total ;
  620. } /* host_write_d */
  621. /*=======================================================================================
  622. */
  623. static sf_count_t
  624. replace_read_d2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
  625. { int bufferlen, readcount ;
  626. sf_count_t total = 0 ;
  627. double scale ;
  628. bufferlen = ARRAY_LEN (psf->u.dbuf) ;
  629. scale = (psf->float_int_mult == 0) ? 1.0 : 0x7FFF / psf->float_max ;
  630. while (len > 0)
  631. { if (len < bufferlen)
  632. bufferlen = (int) len ;
  633. readcount = psf_fread (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
  634. if (psf->data_endswap == SF_TRUE)
  635. endswap_double_array (psf->u.dbuf, bufferlen) ;
  636. d2bd_read (psf->u.dbuf, bufferlen) ;
  637. d2s_array (psf->u.dbuf, readcount, ptr + total, scale) ;
  638. total += readcount ;
  639. if (readcount < bufferlen)
  640. break ;
  641. len -= readcount ;
  642. } ;
  643. return total ;
  644. } /* replace_read_d2s */
  645. static sf_count_t
  646. replace_read_d2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
  647. { int bufferlen, readcount ;
  648. sf_count_t total = 0 ;
  649. double scale ;
  650. bufferlen = ARRAY_LEN (psf->u.dbuf) ;
  651. scale = (psf->float_int_mult == 0) ? 1.0 : 0x7FFFFFFF / psf->float_max ;
  652. while (len > 0)
  653. { if (len < bufferlen)
  654. bufferlen = (int) len ;
  655. readcount = psf_fread (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
  656. if (psf->data_endswap == SF_TRUE)
  657. endswap_double_array (psf->u.dbuf, bufferlen) ;
  658. d2bd_read (psf->u.dbuf, bufferlen) ;
  659. d2i_array (psf->u.dbuf, readcount, ptr + total, scale) ;
  660. total += readcount ;
  661. if (readcount < bufferlen)
  662. break ;
  663. len -= readcount ;
  664. } ;
  665. return total ;
  666. } /* replace_read_d2i */
  667. static sf_count_t
  668. replace_read_d2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
  669. { int bufferlen, readcount ;
  670. sf_count_t total = 0 ;
  671. bufferlen = ARRAY_LEN (psf->u.dbuf) ;
  672. while (len > 0)
  673. { if (len < bufferlen)
  674. bufferlen = (int) len ;
  675. readcount = psf_fread (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
  676. if (psf->data_endswap == SF_TRUE)
  677. endswap_double_array (psf->u.dbuf, bufferlen) ;
  678. d2bd_read (psf->u.dbuf, bufferlen) ;
  679. memcpy (ptr + total, psf->u.dbuf, bufferlen * sizeof (double)) ;
  680. total += readcount ;
  681. if (readcount < bufferlen)
  682. break ;
  683. len -= readcount ;
  684. } ;
  685. return total ;
  686. } /* replace_read_d2f */
  687. static sf_count_t
  688. replace_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
  689. { int bufferlen, readcount ;
  690. sf_count_t total = 0 ;
  691. /* FIXME : This is probably nowhere near optimal. */
  692. bufferlen = ARRAY_LEN (psf->u.dbuf) ;
  693. while (len > 0)
  694. { if (len < bufferlen)
  695. bufferlen = (int) len ;
  696. readcount = psf_fread (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
  697. if (psf->data_endswap == SF_TRUE)
  698. endswap_double_array (psf->u.dbuf, readcount) ;
  699. d2bd_read (psf->u.dbuf, readcount) ;
  700. memcpy (ptr + total, psf->u.dbuf, readcount * sizeof (double)) ;
  701. total += readcount ;
  702. if (readcount < bufferlen)
  703. break ;
  704. len -= readcount ;
  705. } ;
  706. return total ;
  707. } /* replace_read_d */
  708. static sf_count_t
  709. replace_write_s2d (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
  710. { int bufferlen, writecount ;
  711. sf_count_t total = 0 ;
  712. double scale ;
  713. scale = (psf->scale_int_float == 0) ? 1.0 : 1.0 / 0x8000 ;
  714. bufferlen = ARRAY_LEN (psf->u.dbuf) ;
  715. while (len > 0)
  716. { if (len < bufferlen)
  717. bufferlen = (int) len ;
  718. s2d_array (ptr + total, psf->u.dbuf, bufferlen, scale) ;
  719. if (psf->peak_info)
  720. double64_peak_update (psf, psf->u.dbuf, bufferlen, total / psf->sf.channels) ;
  721. bd2d_write (psf->u.dbuf, bufferlen) ;
  722. if (psf->data_endswap == SF_TRUE)
  723. endswap_double_array (psf->u.dbuf, bufferlen) ;
  724. writecount = psf_fwrite (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
  725. total += writecount ;
  726. if (writecount < bufferlen)
  727. break ;
  728. len -= writecount ;
  729. } ;
  730. return total ;
  731. } /* replace_write_s2d */
  732. static sf_count_t
  733. replace_write_i2d (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
  734. { int bufferlen, writecount ;
  735. sf_count_t total = 0 ;
  736. double scale ;
  737. scale = (psf->scale_int_float == 0) ? 1.0 : 1.0 / (8.0 * 0x10000000) ;
  738. bufferlen = ARRAY_LEN (psf->u.dbuf) ;
  739. while (len > 0)
  740. { if (len < bufferlen)
  741. bufferlen = (int) len ;
  742. i2d_array (ptr + total, psf->u.dbuf, bufferlen, scale) ;
  743. if (psf->peak_info)
  744. double64_peak_update (psf, psf->u.dbuf, bufferlen, total / psf->sf.channels) ;
  745. bd2d_write (psf->u.dbuf, bufferlen) ;
  746. if (psf->data_endswap == SF_TRUE)
  747. endswap_double_array (psf->u.dbuf, bufferlen) ;
  748. writecount = psf_fwrite (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
  749. total += writecount ;
  750. if (writecount < bufferlen)
  751. break ;
  752. len -= writecount ;
  753. } ;
  754. return total ;
  755. } /* replace_write_i2d */
  756. static sf_count_t
  757. replace_write_f2d (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
  758. { int bufferlen, writecount ;
  759. sf_count_t total = 0 ;
  760. bufferlen = ARRAY_LEN (psf->u.dbuf) ;
  761. while (len > 0)
  762. { if (len < bufferlen)
  763. bufferlen = (int) len ;
  764. f2d_array (ptr + total, psf->u.dbuf, bufferlen) ;
  765. bd2d_write (psf->u.dbuf, bufferlen) ;
  766. if (psf->data_endswap == SF_TRUE)
  767. endswap_double_array (psf->u.dbuf, bufferlen) ;
  768. writecount = psf_fwrite (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
  769. total += writecount ;
  770. if (writecount < bufferlen)
  771. break ;
  772. len -= writecount ;
  773. } ;
  774. return total ;
  775. } /* replace_write_f2d */
  776. static sf_count_t
  777. replace_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
  778. { int bufferlen, writecount ;
  779. sf_count_t total = 0 ;
  780. /* FIXME : This is probably nowhere near optimal. */
  781. if (psf->peak_info)
  782. double64_peak_update (psf, ptr, len, 0) ;
  783. bufferlen = ARRAY_LEN (psf->u.dbuf) ;
  784. while (len > 0)
  785. { if (len < bufferlen)
  786. bufferlen = (int) len ;
  787. memcpy (psf->u.dbuf, ptr + total, bufferlen * sizeof (double)) ;
  788. bd2d_write (psf->u.dbuf, bufferlen) ;
  789. if (psf->data_endswap == SF_TRUE)
  790. endswap_double_array (psf->u.dbuf, bufferlen) ;
  791. writecount = psf_fwrite (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
  792. total += writecount ;
  793. if (writecount < bufferlen)
  794. break ;
  795. len -= writecount ;
  796. } ;
  797. return total ;
  798. } /* replace_write_d */
  799. /*----------------------------------------------------------------------------------------------
  800. */
  801. static void
  802. d2bd_read (double *buffer, int count)
  803. { while (--count >= 0)
  804. { buffer [count] = DOUBLE64_READ ((unsigned char *) (buffer + count)) ;
  805. } ;
  806. } /* d2bd_read */
  807. static void
  808. bd2d_write (double *buffer, int count)
  809. { while (--count >= 0)
  810. { DOUBLE64_WRITE (buffer [count], (unsigned char*) (buffer + count)) ;
  811. } ;
  812. } /* bd2d_write */