paf.c
上传用户:shw771010
上传日期:2022-01-05
资源大小:991k
文件大小:23k
源码类别:

Audio

开发平台:

Unix_Linux

  1. /*
  2. ** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
  3. **
  4. ** This program is free software; you can redistribute it and/or modify
  5. ** it under the terms of the GNU Lesser General Public License as published by
  6. ** the Free Software Foundation; either version 2.1 of the License, or
  7. ** (at your option) any later version.
  8. **
  9. ** This program is distributed in the hope that it will be useful,
  10. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. ** GNU Lesser General Public License for more details.
  13. **
  14. ** You should have received a copy of the GNU Lesser General Public License
  15. ** along with this program; if not, write to the Free Software
  16. ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17. */
  18. #include "sfconfig.h"
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <fcntl.h>
  22. #include <string.h>
  23. #include <ctype.h>
  24. #include <math.h>
  25. #include "sndfile.h"
  26. #include "sfendian.h"
  27. #include "common.h"
  28. /*------------------------------------------------------------------------------
  29. ** Macros to handle big/little endian issues.
  30. */
  31. #define FAP_MARKER (MAKE_MARKER ('f', 'a', 'p', ' '))
  32. #define PAF_MARKER (MAKE_MARKER (' ', 'p', 'a', 'f'))
  33. /*------------------------------------------------------------------------------
  34. ** Other defines.
  35. */
  36. #define PAF_HEADER_LENGTH  2048
  37. #define PAF24_SAMPLES_PER_BLOCK 10
  38. #define PAF24_BLOCK_SIZE 32
  39. /*------------------------------------------------------------------------------
  40. ** Typedefs.
  41. */
  42. typedef struct
  43. { int version ;
  44. int endianness ;
  45.     int samplerate ;
  46.     int format ;
  47. int channels ;
  48. int source ;
  49. } PAF_FMT ;
  50. typedef struct
  51. { int max_blocks, channels, samplesperblock, blocksize ;
  52. int read_block, write_block, read_count, write_count ;
  53. sf_count_t sample_count ;
  54. int *samples ;
  55. unsigned char *block ;
  56. #if HAVE_FLEXIBLE_ARRAY
  57. int data [] ; /* ISO C99 struct flexible array. */
  58. #else
  59. int data [1] ; /* This is a hack and may not work. */
  60. #endif
  61. } PAF24_PRIVATE ;
  62. /*------------------------------------------------------------------------------
  63. ** Private static functions.
  64. */
  65. static int paf24_init (SF_PRIVATE *psf) ;
  66. static int paf_read_header (SF_PRIVATE *psf) ;
  67. static int paf_write_header (SF_PRIVATE *psf, int calc_length) ;
  68. static sf_count_t paf24_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
  69. static sf_count_t paf24_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
  70. static sf_count_t paf24_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
  71. static sf_count_t paf24_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
  72. static sf_count_t paf24_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
  73. static sf_count_t paf24_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
  74. static sf_count_t paf24_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
  75. static sf_count_t paf24_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
  76. static sf_count_t paf24_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
  77. enum
  78. { PAF_PCM_16 = 0,
  79. PAF_PCM_24 = 1,
  80. PAF_PCM_S8 = 2
  81. } ;
  82. /*------------------------------------------------------------------------------
  83. ** Public function.
  84. */
  85. int
  86. paf_open (SF_PRIVATE *psf)
  87. { int subformat, error, endian ;
  88.   psf->dataoffset = PAF_HEADER_LENGTH ;
  89. if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
  90. { if ((error = paf_read_header (psf)))
  91. return error ;
  92. } ;
  93. subformat = SF_CODEC (psf->sf.format) ;
  94. if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
  95. { if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_PAF)
  96. return SFE_BAD_OPEN_FORMAT ;
  97. endian = SF_ENDIAN (psf->sf.format) ;
  98. /* PAF is by default big endian. */
  99. psf->endian = SF_ENDIAN_BIG ;
  100. if (endian == SF_ENDIAN_LITTLE || (CPU_IS_LITTLE_ENDIAN && (endian == SF_ENDIAN_CPU)))
  101. psf->endian = SF_ENDIAN_LITTLE ;
  102. if ((error = paf_write_header (psf, SF_FALSE)))
  103. return error ;
  104. psf->write_header = paf_write_header ;
  105. } ;
  106. switch (subformat)
  107. { case SF_FORMAT_PCM_S8 :
  108. psf->bytewidth = 1 ;
  109. error = pcm_init (psf) ;
  110. break ;
  111. case SF_FORMAT_PCM_16 :
  112. psf->bytewidth = 2 ;
  113. error = pcm_init (psf) ;
  114. break ;
  115. case SF_FORMAT_PCM_24 :
  116. /* No bytewidth because of whacky 24 bit encoding. */
  117. error = paf24_init (psf) ;
  118. break ;
  119. default : return SFE_PAF_UNKNOWN_FORMAT ;
  120. } ;
  121. return error ;
  122. } /* paf_open */
  123. /*------------------------------------------------------------------------------
  124. */
  125. static int
  126. paf_read_header (SF_PRIVATE *psf)
  127. { PAF_FMT paf_fmt ;
  128. int marker ;
  129. memset (&paf_fmt, 0, sizeof (paf_fmt)) ;
  130. psf_binheader_readf (psf, "pm", 0, &marker) ;
  131. psf_log_printf (psf, "Signature   : '%M'n", marker) ;
  132. if (marker == PAF_MARKER)
  133. { psf_binheader_readf (psf, "E444444", &(paf_fmt.version), &(paf_fmt.endianness),
  134. &(paf_fmt.samplerate), &(paf_fmt.format), &(paf_fmt.channels), &(paf_fmt.source)) ;
  135. }
  136. else if (marker == FAP_MARKER)
  137. { psf_binheader_readf (psf, "e444444", &(paf_fmt.version), &(paf_fmt.endianness),
  138. &(paf_fmt.samplerate), &(paf_fmt.format), &(paf_fmt.channels), &(paf_fmt.source)) ;
  139. }
  140. else
  141. return SFE_PAF_NO_MARKER ;
  142. psf_log_printf (psf, "Version     : %dn", paf_fmt.version) ;
  143. if (paf_fmt.version != 0)
  144. { psf_log_printf (psf, "*** Bad version number. should be zero.n") ;
  145. return SFE_PAF_VERSION ;
  146. } ;
  147. psf_log_printf (psf, "Sample Rate : %dn", paf_fmt.samplerate) ;
  148. psf_log_printf (psf, "Channels    : %dn", paf_fmt.channels) ;
  149. psf_log_printf (psf, "Endianness  : %d => ", paf_fmt.endianness) ;
  150. if (paf_fmt.endianness)
  151. { psf_log_printf (psf, "Littlen", paf_fmt.endianness) ;
  152. psf->endian = SF_ENDIAN_LITTLE ;
  153. }
  154. else
  155. { psf_log_printf (psf, "Bign", paf_fmt.endianness) ;
  156. psf->endian = SF_ENDIAN_BIG ;
  157. } ;
  158. if (psf->filelength < PAF_HEADER_LENGTH)
  159. return SFE_PAF_SHORT_HEADER ;
  160. psf->datalength = psf->filelength - psf->dataoffset ;
  161. psf_binheader_readf (psf, "p", (int) psf->dataoffset) ;
  162. psf->sf.samplerate = paf_fmt.samplerate ;
  163. psf->sf.channels  = paf_fmt.channels ;
  164. /* Only fill in type major. */
  165. psf->sf.format = SF_FORMAT_PAF ;
  166. psf_log_printf (psf, "Format      : %d => ", paf_fmt.format) ;
  167. /* PAF is by default big endian. */
  168. psf->sf.format |= paf_fmt.endianness ? SF_ENDIAN_LITTLE : SF_ENDIAN_BIG ;
  169. switch (paf_fmt.format)
  170. { case PAF_PCM_S8 :
  171. psf_log_printf (psf, "8 bit linear PCMn") ;
  172. psf->bytewidth = 1 ;
  173. psf->sf.format |= SF_FORMAT_PCM_S8 ;
  174. psf->blockwidth = psf->bytewidth * psf->sf.channels ;
  175. psf->sf.frames = psf->datalength / psf->blockwidth ;
  176. break ;
  177. case PAF_PCM_16 :
  178. psf_log_printf (psf, "16 bit linear PCMn") ;
  179. psf->bytewidth = 2 ;
  180. psf->sf.format |= SF_FORMAT_PCM_16 ;
  181. psf->blockwidth = psf->bytewidth * psf->sf.channels ;
  182. psf->sf.frames = psf->datalength / psf->blockwidth ;
  183. break ;
  184. case PAF_PCM_24 :
  185. psf_log_printf (psf, "24 bit linear PCMn") ;
  186. psf->bytewidth = 3 ;
  187. psf->sf.format |= SF_FORMAT_PCM_24 ;
  188. psf->blockwidth = 0 ;
  189. psf->sf.frames = PAF24_SAMPLES_PER_BLOCK * psf->datalength /
  190. (PAF24_BLOCK_SIZE * psf->sf.channels) ;
  191. break ;
  192. default : psf_log_printf (psf, "Unknownn") ;
  193. return SFE_PAF_UNKNOWN_FORMAT ;
  194. break ;
  195. } ;
  196. psf_log_printf (psf, "Source      : %d => ", paf_fmt.source) ;
  197. switch (paf_fmt.source)
  198. { case 1 : psf_log_printf (psf, "Analog Recordingn") ;
  199. break ;
  200. case 2 : psf_log_printf (psf, "Digital Transfern") ;
  201. break ;
  202. case 3 : psf_log_printf (psf, "Multi-track Mixdownn") ;
  203. break ;
  204. case 5 : psf_log_printf (psf, "Audio Resulting From DSP Processingn") ;
  205. break ;
  206. default : psf_log_printf (psf, "Unknownn") ;
  207. break ;
  208. } ;
  209. return 0 ;
  210. } /* paf_read_header */
  211. static int
  212. paf_write_header (SF_PRIVATE *psf, int UNUSED (calc_length))
  213. { int paf_format ;
  214. /* PAF header already written so no need to re-write. */
  215. if (psf_ftell (psf) >= PAF_HEADER_LENGTH)
  216. return 0 ;
  217. psf->dataoffset = PAF_HEADER_LENGTH ;
  218. switch (SF_CODEC (psf->sf.format))
  219. { case SF_FORMAT_PCM_S8 :
  220. paf_format = PAF_PCM_S8 ;
  221. break ;
  222. case SF_FORMAT_PCM_16 :
  223. paf_format = PAF_PCM_16 ;
  224. break ;
  225. case SF_FORMAT_PCM_24 :
  226. paf_format = PAF_PCM_24 ;
  227. break ;
  228. default : return SFE_PAF_UNKNOWN_FORMAT ;
  229. } ;
  230. /* Reset the current header length to zero. */
  231. psf->header [0] = 0 ;
  232. psf->headindex = 0 ;
  233. if (psf->endian == SF_ENDIAN_BIG)
  234. { /* Marker, version, endianness, samplerate */
  235. psf_binheader_writef (psf, "Em444", PAF_MARKER, 0, 0, psf->sf.samplerate) ;
  236. /* format, channels, source */
  237. psf_binheader_writef (psf, "E444", paf_format, psf->sf.channels, 0) ;
  238. }
  239. else if (psf->endian == SF_ENDIAN_LITTLE)
  240. { /* Marker, version, endianness, samplerate */
  241. psf_binheader_writef (psf, "em444", FAP_MARKER, 0, 1, psf->sf.samplerate) ;
  242. /* format, channels, source */
  243. psf_binheader_writef (psf, "e444", paf_format, psf->sf.channels, 0) ;
  244. } ;
  245. /* Zero fill to dataoffset. */
  246. psf_binheader_writef (psf, "z", (size_t) (psf->dataoffset - psf->headindex)) ;
  247. psf_fwrite (psf->header, psf->headindex, 1, psf) ;
  248. return psf->error ;
  249. } /* paf_write_header */
  250. /*===============================================================================
  251. ** 24 bit PAF files have a really weird encoding.
  252. **  For a mono file, 10 samples (each being 3 bytes) are packed into a 32 byte
  253. ** block. The 8 ints in this 32 byte block are then endian swapped (as ints)
  254. ** if necessary before being written to disk.
  255. **  For a stereo file, blocks of 10 samples from the same channel are encoded
  256. **  into 32 bytes as for the mono case. The 32 byte blocks are then interleaved
  257. ** on disk.
  258. ** Reading has to reverse the above process :-).
  259. ** Weird!!!
  260. **
  261. ** The code below attempts to gain efficiency while maintaining readability.
  262. */
  263. static int paf24_read_block (SF_PRIVATE *psf, PAF24_PRIVATE *ppaf24) ;
  264. static int paf24_write_block (SF_PRIVATE *psf, PAF24_PRIVATE *ppaf24) ;
  265. static int paf24_close (SF_PRIVATE *psf) ;
  266. static int
  267. paf24_init (SF_PRIVATE *psf)
  268. { PAF24_PRIVATE *ppaf24 ;
  269. int paf24size ;
  270. paf24size = sizeof (PAF24_PRIVATE) + psf->sf.channels *
  271. (PAF24_BLOCK_SIZE + PAF24_SAMPLES_PER_BLOCK * sizeof (int)) ;
  272. /*
  273. ** Not exatly sure why this needs to be here but the tests
  274. ** fail without it.
  275. */
  276. psf->last_op = 0 ;
  277. if (! (psf->codec_data = malloc (paf24size)))
  278. return SFE_MALLOC_FAILED ;
  279. ppaf24 = (PAF24_PRIVATE*) psf->codec_data ;
  280. memset (ppaf24, 0, paf24size) ;
  281. ppaf24->channels = psf->sf.channels ;
  282. ppaf24->samples = ppaf24->data ;
  283. ppaf24->block = (unsigned char*) (ppaf24->data + PAF24_SAMPLES_PER_BLOCK * ppaf24->channels) ;
  284. ppaf24->blocksize = PAF24_BLOCK_SIZE * ppaf24->channels ;
  285. ppaf24->samplesperblock = PAF24_SAMPLES_PER_BLOCK ;
  286. if (psf->file.mode == SFM_READ || psf->file.mode == SFM_RDWR)
  287. { paf24_read_block (psf, ppaf24) ; /* Read first block. */
  288. psf->read_short = paf24_read_s ;
  289. psf->read_int = paf24_read_i ;
  290. psf->read_float = paf24_read_f ;
  291. psf->read_double = paf24_read_d ;
  292. } ;
  293. if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
  294. { psf->write_short = paf24_write_s ;
  295. psf->write_int = paf24_write_i ;
  296. psf->write_float = paf24_write_f ;
  297. psf->write_double = paf24_write_d ;
  298. } ;
  299. psf->seek = paf24_seek ;
  300. psf->container_close = paf24_close ;
  301. psf->filelength = psf_get_filelen (psf) ;
  302. psf->datalength = psf->filelength - psf->dataoffset ;
  303. if (psf->datalength % PAF24_BLOCK_SIZE)
  304. { if (psf->file.mode == SFM_READ)
  305. psf_log_printf (psf, "*** Warning : file seems to be truncated.n") ;
  306. ppaf24->max_blocks = psf->datalength / ppaf24->blocksize + 1 ;
  307. }
  308. else
  309. ppaf24->max_blocks = psf->datalength / ppaf24->blocksize ;
  310. ppaf24->read_block = 0 ;
  311. if (psf->file.mode == SFM_RDWR)
  312. ppaf24->write_block = ppaf24->max_blocks ;
  313. else
  314. ppaf24->write_block = 0 ;
  315. psf->sf.frames = ppaf24->samplesperblock * ppaf24->max_blocks ;
  316. ppaf24->sample_count = psf->sf.frames ;
  317. return 0 ;
  318. } /* paf24_init */
  319. static sf_count_t
  320. paf24_seek (SF_PRIVATE *psf, int mode, sf_count_t offset)
  321. { PAF24_PRIVATE *ppaf24 ;
  322. int newblock, newsample ;
  323. if (psf->codec_data == NULL)
  324. { psf->error = SFE_INTERNAL ;
  325. return PSF_SEEK_ERROR ;
  326. } ;
  327. ppaf24 = (PAF24_PRIVATE*) psf->codec_data ;
  328. if (mode == SFM_READ && ppaf24->write_count > 0)
  329. paf24_write_block (psf, ppaf24) ;
  330. newblock = offset / ppaf24->samplesperblock ;
  331. newsample = offset % ppaf24->samplesperblock ;
  332. switch (mode)
  333. { case SFM_READ :
  334. if (psf->last_op == SFM_WRITE && ppaf24->write_count)
  335. paf24_write_block (psf, ppaf24) ;
  336. psf_fseek (psf, psf->dataoffset + newblock * ppaf24->blocksize, SEEK_SET) ;
  337. ppaf24->read_block = newblock ;
  338. paf24_read_block (psf, ppaf24) ;
  339. ppaf24->read_count = newsample ;
  340. break ;
  341. case SFM_WRITE :
  342. if (offset > ppaf24->sample_count)
  343. { psf->error = SFE_BAD_SEEK ;
  344. return PSF_SEEK_ERROR ;
  345. } ;
  346. if (psf->last_op == SFM_WRITE && ppaf24->write_count)
  347. paf24_write_block (psf, ppaf24) ;
  348. psf_fseek (psf, psf->dataoffset + newblock * ppaf24->blocksize, SEEK_SET) ;
  349. ppaf24->write_block = newblock ;
  350. paf24_read_block (psf, ppaf24) ;
  351. ppaf24->write_count = newsample ;
  352. break ;
  353. default :
  354. psf->error = SFE_BAD_SEEK ;
  355. return PSF_SEEK_ERROR ;
  356. } ;
  357. return newblock * ppaf24->samplesperblock + newsample ;
  358. } /* paf24_seek */
  359. static int
  360. paf24_close (SF_PRIVATE *psf)
  361. { PAF24_PRIVATE *ppaf24 ;
  362. if (psf->codec_data == NULL)
  363. return 0 ;
  364. ppaf24 = (PAF24_PRIVATE*) psf->codec_data ;
  365. if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
  366. { if (ppaf24->write_count > 0)
  367. paf24_write_block (psf, ppaf24) ;
  368. } ;
  369. return 0 ;
  370. } /* paf24_close */
  371. /*---------------------------------------------------------------------------
  372. */
  373. static int
  374. paf24_read_block (SF_PRIVATE *psf, PAF24_PRIVATE *ppaf24)
  375. { int k, channel ;
  376. unsigned char *cptr ;
  377. ppaf24->read_block ++ ;
  378. ppaf24->read_count = 0 ;
  379. if (ppaf24->read_block * ppaf24->samplesperblock > ppaf24->sample_count)
  380. { memset (ppaf24->samples, 0, ppaf24->samplesperblock * ppaf24->channels) ;
  381. return 1 ;
  382. } ;
  383. /* Read the block. */
  384. if ((k = psf_fread (ppaf24->block, 1, ppaf24->blocksize, psf)) != ppaf24->blocksize)
  385. psf_log_printf (psf, "*** Warning : short read (%d != %d).n", k, ppaf24->blocksize) ;
  386. if (CPU_IS_LITTLE_ENDIAN)
  387. { /* Do endian swapping if necessary. */
  388. if (psf->endian == SF_ENDIAN_BIG)
  389. endswap_int_array  (ppaf24->data, 8 * ppaf24->channels) ;
  390. /* Unpack block. */
  391. for (k = 0 ; k < PAF24_SAMPLES_PER_BLOCK * ppaf24->channels ; k++)
  392. { channel = k % ppaf24->channels ;
  393. cptr = ppaf24->block + PAF24_BLOCK_SIZE * channel + 3 * (k / ppaf24->channels) ;
  394. ppaf24->samples [k] = (cptr [0] << 8) | (cptr [1] << 16) | (cptr [2] << 24) ;
  395. } ;
  396. }
  397. else
  398. { /* Do endian swapping if necessary. */
  399. if (psf->endian == SF_ENDIAN_BIG)
  400. endswap_int_array  (ppaf24->data, 8 * ppaf24->channels) ;
  401. /* Unpack block. */
  402. for (k = 0 ; k < PAF24_SAMPLES_PER_BLOCK * ppaf24->channels ; k++)
  403. { channel = k % ppaf24->channels ;
  404. cptr = ppaf24->block + PAF24_BLOCK_SIZE * channel + 3 * (k / ppaf24->channels) ;
  405. ppaf24->samples [k] = (cptr [0] << 8) | (cptr [1] << 16) | (cptr [2] << 24) ;
  406. } ;
  407. } ;
  408. return 1 ;
  409. } /* paf24_read_block */
  410. static int
  411. paf24_read (SF_PRIVATE *psf, PAF24_PRIVATE *ppaf24, int *ptr, int len)
  412. { int count, total = 0 ;
  413. while (total < len)
  414. { if (ppaf24->read_block * ppaf24->samplesperblock >= ppaf24->sample_count)
  415. { memset (&(ptr [total]), 0, (len - total) * sizeof (int)) ;
  416. return total ;
  417. } ;
  418. if (ppaf24->read_count >= ppaf24->samplesperblock)
  419. paf24_read_block (psf, ppaf24) ;
  420. count = (ppaf24->samplesperblock - ppaf24->read_count) * ppaf24->channels ;
  421. count = (len - total > count) ? count : len - total ;
  422. memcpy (&(ptr [total]), &(ppaf24->samples [ppaf24->read_count * ppaf24->channels]), count * sizeof (int)) ;
  423. total += count ;
  424. ppaf24->read_count += count / ppaf24->channels ;
  425. } ;
  426. return total ;
  427. } /* paf24_read */
  428. static sf_count_t
  429. paf24_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
  430. { PAF24_PRIVATE  *ppaf24 ;
  431. int *iptr ;
  432. int k, bufferlen, readcount, count ;
  433. sf_count_t total = 0 ;
  434. if (psf->codec_data == NULL)
  435. return 0 ;
  436. ppaf24 = (PAF24_PRIVATE*) psf->codec_data ;
  437. iptr = psf->u.ibuf ;
  438. bufferlen = ARRAY_LEN (psf->u.ibuf) ;
  439. while (len > 0)
  440. { readcount = (len >= bufferlen) ? bufferlen : len ;
  441. count = paf24_read (psf, ppaf24, iptr, readcount) ;
  442. for (k = 0 ; k < readcount ; k++)
  443. ptr [total + k] = iptr [k] >> 16 ;
  444. total += count ;
  445. len -= readcount ;
  446. } ;
  447. return total ;
  448. } /* paf24_read_s */
  449. static sf_count_t
  450. paf24_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
  451. { PAF24_PRIVATE *ppaf24 ;
  452. int total ;
  453. if (psf->codec_data == NULL)
  454. return 0 ;
  455. ppaf24 = (PAF24_PRIVATE*) psf->codec_data ;
  456. total = paf24_read (psf, ppaf24, ptr, len) ;
  457. return total ;
  458. } /* paf24_read_i */
  459. static sf_count_t
  460. paf24_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
  461. { PAF24_PRIVATE  *ppaf24 ;
  462. int *iptr ;
  463. int k, bufferlen, readcount, count ;
  464. sf_count_t total = 0 ;
  465. float normfact ;
  466. if (psf->codec_data == NULL)
  467. return 0 ;
  468. ppaf24 = (PAF24_PRIVATE*) psf->codec_data ;
  469. normfact = (psf->norm_float == SF_TRUE) ? (1.0 / 0x80000000) : (1.0 / 0x100) ;
  470. iptr = psf->u.ibuf ;
  471. bufferlen = ARRAY_LEN (psf->u.ibuf) ;
  472. while (len > 0)
  473. { readcount = (len >= bufferlen) ? bufferlen : len ;
  474. count = paf24_read (psf, ppaf24, iptr, readcount) ;
  475. for (k = 0 ; k < readcount ; k++)
  476. ptr [total + k] = normfact * iptr [k] ;
  477. total += count ;
  478. len -= readcount ;
  479. } ;
  480. return total ;
  481. } /* paf24_read_f */
  482. static sf_count_t
  483. paf24_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
  484. { PAF24_PRIVATE  *ppaf24 ;
  485. int *iptr ;
  486. int k, bufferlen, readcount, count ;
  487. sf_count_t total = 0 ;
  488. double  normfact ;
  489. if (psf->codec_data == NULL)
  490. return 0 ;
  491. ppaf24 = (PAF24_PRIVATE*) psf->codec_data ;
  492. normfact = (psf->norm_double == SF_TRUE) ? (1.0 / 0x80000000) : (1.0 / 0x100) ;
  493. iptr = psf->u.ibuf ;
  494. bufferlen = ARRAY_LEN (psf->u.ibuf) ;
  495. while (len > 0)
  496. { readcount = (len >= bufferlen) ? bufferlen : len ;
  497. count = paf24_read (psf, ppaf24, iptr, readcount) ;
  498. for (k = 0 ; k < readcount ; k++)
  499. ptr [total + k] = normfact * iptr [k] ;
  500. total += count ;
  501. len -= readcount ;
  502. } ;
  503. return total ;
  504. } /* paf24_read_d */
  505. /*---------------------------------------------------------------------------
  506. */
  507. static int
  508. paf24_write_block (SF_PRIVATE *psf, PAF24_PRIVATE *ppaf24)
  509. { int k, nextsample, channel ;
  510. unsigned char *cptr ;
  511. /* First pack block. */
  512. if (CPU_IS_LITTLE_ENDIAN)
  513. { for (k = 0 ; k < PAF24_SAMPLES_PER_BLOCK * ppaf24->channels ; k++)
  514. { channel = k % ppaf24->channels ;
  515. cptr = ppaf24->block + PAF24_BLOCK_SIZE * channel + 3 * (k / ppaf24->channels) ;
  516. nextsample = ppaf24->samples [k] >> 8 ;
  517. cptr [0] = nextsample ;
  518. cptr [1] = nextsample >> 8 ;
  519. cptr [2] = nextsample >> 16 ;
  520. } ;
  521. /* Do endian swapping if necessary. */
  522. if (psf->endian == SF_ENDIAN_BIG)
  523. endswap_int_array (ppaf24->data, 8 * ppaf24->channels) ;
  524. }
  525. else if (CPU_IS_BIG_ENDIAN)
  526. { /* This is correct. */
  527. for (k = 0 ; k < PAF24_SAMPLES_PER_BLOCK * ppaf24->channels ; k++)
  528. { channel = k % ppaf24->channels ;
  529. cptr = ppaf24->block + PAF24_BLOCK_SIZE * channel + 3 * (k / ppaf24->channels) ;
  530. nextsample = ppaf24->samples [k] >> 8 ;
  531. cptr [0] = nextsample ;
  532. cptr [1] = nextsample >> 8 ;
  533. cptr [2] = nextsample >> 16 ;
  534. } ;
  535. if (psf->endian == SF_ENDIAN_BIG)
  536. endswap_int_array (ppaf24->data, 8 * ppaf24->channels) ;
  537. } ;
  538. /* Write block to disk. */
  539. if ((k = psf_fwrite (ppaf24->block, 1, ppaf24->blocksize, psf)) != ppaf24->blocksize)
  540. psf_log_printf (psf, "*** Warning : short write (%d != %d).n", k, ppaf24->blocksize) ;
  541. if (ppaf24->sample_count < ppaf24->write_block * ppaf24->samplesperblock + ppaf24->write_count)
  542. ppaf24->sample_count = ppaf24->write_block * ppaf24->samplesperblock + ppaf24->write_count ;
  543. if (ppaf24->write_count == ppaf24->samplesperblock)
  544. { ppaf24->write_block ++ ;
  545. ppaf24->write_count = 0 ;
  546. } ;
  547. return 1 ;
  548. } /* paf24_write_block */
  549. static int
  550. paf24_write (SF_PRIVATE *psf, PAF24_PRIVATE *ppaf24, const int *ptr, int len)
  551. { int count, total = 0 ;
  552. while (total < len)
  553. { count = (ppaf24->samplesperblock - ppaf24->write_count) * ppaf24->channels ;
  554. if (count > len - total)
  555. count = len - total ;
  556. memcpy (&(ppaf24->samples [ppaf24->write_count * ppaf24->channels]), &(ptr [total]), count * sizeof (int)) ;
  557. total += count ;
  558. ppaf24->write_count += count / ppaf24->channels ;
  559. if (ppaf24->write_count >= ppaf24->samplesperblock)
  560. paf24_write_block (psf, ppaf24) ;
  561. } ;
  562. return total ;
  563. } /* paf24_write */
  564. static sf_count_t
  565. paf24_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
  566. { PAF24_PRIVATE  *ppaf24 ;
  567. int *iptr ;
  568. int k, bufferlen, writecount = 0, count ;
  569. sf_count_t total = 0 ;
  570. if (psf->codec_data == NULL)
  571. return 0 ;
  572. ppaf24 = (PAF24_PRIVATE*) psf->codec_data ;
  573. iptr = psf->u.ibuf ;
  574. bufferlen = ARRAY_LEN (psf->u.ibuf) ;
  575. while (len > 0)
  576. { writecount = (len >= bufferlen) ? bufferlen : len ;
  577. for (k = 0 ; k < writecount ; k++)
  578. iptr [k] = ptr [total + k] << 16 ;
  579. count = paf24_write (psf, ppaf24, iptr, writecount) ;
  580. total += count ;
  581. len -= writecount ;
  582. if (count != writecount)
  583. break ;
  584. } ;
  585. return total ;
  586. } /* paf24_write_s */
  587. static sf_count_t
  588. paf24_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
  589. { PAF24_PRIVATE  *ppaf24 ;
  590. int writecount, count ;
  591. sf_count_t total = 0 ;
  592. if (psf->codec_data == NULL)
  593. return 0 ;
  594. ppaf24 = (PAF24_PRIVATE*) psf->codec_data ;
  595. while (len > 0)
  596. { writecount = (len > 0x10000000) ? 0x10000000 : (int) len ;
  597. count = paf24_write (psf, ppaf24, ptr, writecount) ;
  598. total += count ;
  599. len -= count ;
  600. if (count != writecount)
  601. break ;
  602. } ;
  603. return total ;
  604. } /* paf24_write_i */
  605. static sf_count_t
  606. paf24_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
  607. { PAF24_PRIVATE  *ppaf24 ;
  608. int *iptr ;
  609. int k, bufferlen, writecount = 0, count ;
  610. sf_count_t total = 0 ;
  611. float normfact ;
  612. if (psf->codec_data == NULL)
  613. return 0 ;
  614. ppaf24 = (PAF24_PRIVATE*) psf->codec_data ;
  615. normfact = (psf->norm_float == SF_TRUE) ? (1.0 * 0x7FFFFFFF) : (1.0 / 0x100) ;
  616. iptr = psf->u.ibuf ;
  617. bufferlen = ARRAY_LEN (psf->u.ibuf) ;
  618. while (len > 0)
  619. { writecount = (len >= bufferlen) ? bufferlen : len ;
  620. for (k = 0 ; k < writecount ; k++)
  621. iptr [k] = lrintf (normfact * ptr [total + k]) ;
  622. count = paf24_write (psf, ppaf24, iptr, writecount) ;
  623. total += count ;
  624. len -= writecount ;
  625. if (count != writecount)
  626. break ;
  627. } ;
  628. return total ;
  629. } /* paf24_write_f */
  630. static sf_count_t
  631. paf24_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
  632. { PAF24_PRIVATE  *ppaf24 ;
  633. int *iptr ;
  634. int k, bufferlen, writecount = 0, count ;
  635. sf_count_t total = 0 ;
  636. double normfact ;
  637. if (psf->codec_data == NULL)
  638. return 0 ;
  639. ppaf24 = (PAF24_PRIVATE*) psf->codec_data ;
  640. normfact = (psf->norm_double == SF_TRUE) ? (1.0 * 0x7FFFFFFF) : (1.0 / 0x100) ;
  641. iptr = psf->u.ibuf ;
  642. bufferlen = ARRAY_LEN (psf->u.ibuf) ;
  643. while (len > 0)
  644. { writecount = (len >= bufferlen) ? bufferlen : len ;
  645. for (k = 0 ; k < writecount ; k++)
  646. iptr [k] = lrint (normfact * ptr [total+k]) ;
  647. count = paf24_write (psf, ppaf24, iptr, writecount) ;
  648. total += count ;
  649. len -= writecount ;
  650. if (count != writecount)
  651. break ;
  652. } ;
  653. return total ;
  654. } /* paf24_write_d */