wav_ima_adpcm.c
上传用户:sy_wanhua
上传日期:2013-07-25
资源大小:3048k
文件大小:19k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

C/C++

  1. /*
  2. ** Copyright (C) 1999-2000 Erik de Castro Lopo <erikd@zip.com.au>
  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 <stdio.h>
  19. #include <unistd.h>
  20. #include <string.h>
  21. #include <math.h>
  22. #include "sndfile.h"
  23. #include "config.h"
  24. #include "sfendian.h"
  25. #include "common.h"
  26. #include "wav.h"
  27. typedef struct
  28. { unsigned int channels ;
  29. unsigned int blocksize ;
  30. unsigned int samplesperblock ; 
  31. } IMA_ADPCM_PUBLIC ;
  32. typedef struct
  33. { unsigned int channels, blocksize, samplesperblock, blocks ; 
  34. int blockcount, samplecount ;
  35. int previous [2] ;
  36. int stepindex [2] ;
  37. unsigned char *block ;
  38. short *samples ;
  39. unsigned char data [4] ; /* Dummy size */
  40. } IMA_ADPCM_PRIVATE ;
  41. /*============================================================================================
  42. ** Predefined IMA ADPCM data.
  43. */
  44. static int ima_index_adjust [16] = 
  45. { -1, -1, -1, -1, /* +0 - +3, decrease the step size */
  46.      2,  4,  6,  8,     /* +4 - +7, increase the step size */
  47.     -1, -1, -1, -1, /* -0 - -3, decrease the step size */
  48.      2,  4,  6,  8, /* -4 - -7, increase the step size */
  49. } ;
  50. static int ima_step_size [89] = 
  51. { 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 
  52. 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, 
  53. 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963, 
  54. 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327, 
  55. 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442,
  56. 11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 
  57. 32767
  58. } ;
  59. static int ima_read_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima) ;
  60. static int ima_read (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima, short *ptr, int len) ;
  61. static int ima_write_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima) ;
  62. static int ima_write (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima, short *ptr, int len) ;
  63. static unsigned int wav_srate2blocksize (unsigned int srate) ;
  64. /*============================================================================================
  65. ** IMA ADPCM Reader initialisation function.
  66. */
  67. int  ima_reader_init (SF_PRIVATE *psf, IMA_ADPCM_PUBLIC *public)
  68. { IMA_ADPCM_PRIVATE *pima ;
  69. unsigned int pimasize, count ;
  70. if (psf->mode != SF_MODE_READ)
  71. return SFE_BAD_MODE_RW ;
  72. pimasize = sizeof (IMA_ADPCM_PRIVATE) + public->blocksize + 3 * public->channels * public->samplesperblock ;
  73. if (! (pima = malloc (pimasize)))
  74. return SFE_MALLOC_FAILED ;
  75. psf->fdata = (void*) pima ;
  76. memset (pima, 0, pimasize) ;
  77. pima->block   = (unsigned char*) pima->data ;
  78. pima->samples = (short*) (pima->data + public->blocksize) ;
  79. pima->channels        = public->channels ;
  80. pima->blocksize       = public->blocksize ;
  81. pima->samplesperblock = public->samplesperblock ;
  82. if (psf->datalength % pima->blocksize)
  83. { psf_sprintf (psf, "*** Warning : data chunk seems to be truncated.n") ;
  84. pima->blocks = psf->datalength / pima->blocksize  + 1 ;
  85. }
  86. else
  87. pima->blocks = psf->datalength / pima->blocksize ;
  88. count = 2 * (pima->blocksize - 4 * pima->channels) / pima->channels + 1 ;
  89. if (pima->samplesperblock != count)
  90. psf_sprintf (psf, "*** Warning : samplesperblock should be %d.n", count) ;
  91. psf->sf.samples = pima->samplesperblock * pima->blocks ;
  92. ima_read_block (psf, pima) ; /* Read first block. */
  93. return 0 ;
  94. } /* ima_reader_init */
  95. int ima_writer_init (SF_PRIVATE *psf, IMA_ADPCM_PUBLIC *public)
  96. { IMA_ADPCM_PRIVATE *pima ;
  97. unsigned int  pimasize ;
  98. if (psf->mode != SF_MODE_WRITE)
  99. return SFE_BAD_MODE_RW ;
  100. public->blocksize       = wav_srate2blocksize (psf->sf.samplerate) ;
  101. public->samplesperblock = 2 * (public->blocksize - 4 * public->channels) / public->channels + 1 ;
  102. pimasize = sizeof (IMA_ADPCM_PRIVATE) + public->blocksize + 3 * public->channels * public->samplesperblock ;
  103. if (! (pima = malloc (pimasize)))
  104. return SFE_MALLOC_FAILED ;
  105. psf->fdata = (void*) pima ;
  106. memset (pima, 0, pimasize) ;
  107. pima->channels        = public->channels ;
  108. pima->blocksize       = public->blocksize ;
  109. pima->samplesperblock = public->samplesperblock ;
  110. pima->block   = (unsigned char*) pima->data ;
  111. pima->samples = (short*) (pima->data + public->blocksize) ;
  112. pima->samplecount = 0 ;
  113. return 0 ;
  114. } /* ima_writer_init */
  115. /*============================================================================================
  116. ** IMA ADPCM Read Functions.
  117. */
  118. int wav_ima_reader_init (SF_PRIVATE *psf, WAV_FMT *fmt)
  119. { IMA_ADPCM_PUBLIC public ;
  120. public.blocksize       = fmt->ima.blockalign ;
  121. public.channels        = fmt->ima.channels ;
  122. public.samplesperblock = fmt->ima.samplesperblock ;
  123. return ima_reader_init (psf, &public) ;
  124. } /* wav_ima_reader_init */
  125. static
  126. int ima_read_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima)
  127. { int chan, k, current, blockindex, index, indexstart ;
  128. short step, diff, bytecode, stepindex [2] ;
  129. pima->blockcount ++ ;
  130. pima->samplecount = 0 ;
  131. if (pima->blockcount > pima->blocks)
  132. { memset (pima->samples, 0, pima->samplesperblock * pima->channels * sizeof (short)) ;
  133. return 1 ;
  134. } ;
  135. if ((k = fread (pima->block, 1, pima->blocksize, psf->file)) != pima->blocksize)
  136. psf_sprintf (psf, "*** Warning : short read (%d != %d).n", k, pima->blocksize) ;
  137. /* Read and check the block header. */
  138. for (chan = 0 ; chan < pima->channels ; chan++)
  139. { current = pima->block [chan*4] | (pima->block [chan*4+1] << 8) ;
  140. if (current & 0x8000)
  141. current -= 0x10000 ;
  142. stepindex [chan] = pima->block [chan*4+2] ;
  143. if (stepindex [chan] < 0)
  144. stepindex [chan] = 0 ;
  145. else if (stepindex [chan] > 88)
  146. stepindex [chan] = 88 ;
  147. if (pima->block [chan*4+3] != 0)
  148. psf_sprintf (psf, "IMA ADPCM synchronisation error.n") ;
  149. pima->samples [chan] = current ;
  150. /* psf_sprintf (psf, "block %d : channel %d (current, index) : (%d, %d)n", 
  151. ** pima->blockcount, chan,  current, stepindex [chan]) ;
  152. */
  153. } ;
  154. /* Pull apart the packed 4 bit samples and store them in their
  155. ** correct sample positions.
  156. */
  157. blockindex = 4 * pima->channels ;
  158. indexstart = pima->channels ;
  159. while (blockindex <  pima->blocksize)
  160. { for (chan = 0 ; chan < pima->channels ; chan++)
  161. { index = indexstart + chan ;
  162. for (k = 0 ; k < 4 ; k++)
  163. { bytecode = pima->block [blockindex++] ;
  164. pima->samples [index] = bytecode & 0x0F ;
  165. index += pima->channels ;
  166. pima->samples [index] = (bytecode >> 4) & 0x0F ;
  167. index += pima->channels ;
  168. } ;
  169. } ;
  170. indexstart += 8 * pima->channels ;
  171. } ;
  172. /* Decode the encoded 4 bit samples. */
  173. for (k = pima->channels ; k < (pima->samplesperblock * pima->channels) ; k ++)
  174. { chan = (pima->channels > 1) ? (k % 2) : 0 ;
  175. bytecode = pima->samples [k] & 0xF ;
  176. step = ima_step_size [stepindex [chan]] ;
  177. current = pima->samples [k - pima->channels] ;
  178.   
  179. diff = step >> 3 ;
  180. if (bytecode & 1) 
  181. diff += step >> 2 ;
  182. if (bytecode & 2) 
  183. diff += step >> 1 ;
  184. if (bytecode & 4) 
  185. diff += step ;
  186. if (bytecode & 8) 
  187. diff = -diff ;
  188. current += diff ;
  189. if (current > 32767) 
  190. current = 32767;
  191. else if (current < -32768) 
  192. current = -32768 ;
  193. stepindex [chan] += ima_index_adjust [bytecode] ;
  194. if (stepindex [chan] < 0) 
  195. stepindex [chan] = 0 ;
  196. else if (stepindex [chan] > 88) 
  197. stepindex [chan] = 88 ;
  198. pima->samples [k] = current ;
  199. } ;
  200. return 1 ;
  201. } /* ima_read_block */
  202. static
  203. int ima_read (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima, short *ptr, int len)
  204. { int count, total = 0, index = 0 ;
  205. while (index < len)
  206. { if (pima->blockcount >= pima->blocks && pima->samplecount >= pima->samplesperblock)
  207. { memset (&(ptr[index]), 0, (len - index) * sizeof (short)) ;
  208. return total ;
  209. } ;
  210. if (pima->samplecount >= pima->samplesperblock)
  211. ima_read_block (psf, pima) ;
  212. count = (pima->samplesperblock - pima->samplecount) * pima->channels ;
  213. count = (len - index > count) ? count : len - index ;
  214. memcpy (&(ptr[index]), &(pima->samples [pima->samplecount * pima->channels]), count * sizeof (short)) ;
  215. index += count ;
  216. pima->samplecount += count / pima->channels ;
  217. total = index ;
  218. } ;
  219. return total ;
  220. } /* ima_read */
  221. int ima_read_s (SF_PRIVATE *psf, short *ptr, int len)
  222. { IMA_ADPCM_PRIVATE  *pima ; 
  223. int total ;
  224. if (! psf->fdata)
  225. return 0 ;
  226. pima = (IMA_ADPCM_PRIVATE*) psf->fdata ;
  227. total = ima_read (psf, pima, ptr, len) ;
  228. return total ;
  229. } /* ima_read_s */
  230. int ima_read_i  (SF_PRIVATE *psf, int *ptr, int len)
  231. { IMA_ADPCM_PRIVATE *pima ; 
  232. short *sptr ;
  233. int k, bufferlen, readcount = 0, count ;
  234. int index = 0, total = 0 ;
  235. if (! psf->fdata)
  236. return 0 ;
  237. pima = (IMA_ADPCM_PRIVATE*) psf->fdata ;
  238. sptr = (short*) psf->buffer ;
  239. bufferlen = ((SF_BUFFER_LEN / psf->blockwidth) * psf->blockwidth) / sizeof (short) ;
  240. while (len > 0)
  241. { readcount = (len >= bufferlen) ? bufferlen : len ;
  242. count = ima_read (psf, pima, sptr, readcount) ;
  243. for (k = 0 ; k < readcount ; k++)
  244. ptr [index+k] = (int) (sptr [k]) ;
  245. index += readcount ;
  246. total += count ;
  247. len -= readcount ;
  248. } ;
  249. return total ;
  250. } /* ima_read_i */
  251. int ima_read_d  (SF_PRIVATE *psf, double *ptr, int len, int normalize)
  252. { IMA_ADPCM_PRIVATE *pima ; 
  253. short *sptr ;
  254. int k, bufferlen, readcount = 0, count ;
  255. int index = 0, total = 0 ;
  256. double  normfact ;
  257. normfact = (normalize ? 1.0 / ((double) 0x8000) : 1.0) ;
  258. if (! psf->fdata)
  259. return 0 ;
  260. pima = (IMA_ADPCM_PRIVATE*) psf->fdata ;
  261. sptr = (short*) psf->buffer ;
  262. bufferlen = ((SF_BUFFER_LEN / psf->blockwidth) * psf->blockwidth) / sizeof (short) ;
  263. while (len > 0)
  264. { readcount = (len >= bufferlen) ? bufferlen : len ;
  265. count = ima_read (psf, pima, sptr, readcount) ;
  266. for (k = 0 ; k < readcount ; k++)
  267. ptr [index+k] = normfact * (double) (sptr [k]) ;
  268. index += readcount ;
  269. total += count ;
  270. len -= readcount ;
  271. } ;
  272. return total ;
  273. } /* ima_read_d */
  274. off_t    ima_seek   (SF_PRIVATE *psf, off_t offset, int whence)
  275. { IMA_ADPCM_PRIVATE *pima ; 
  276. int newblock, newsample ;
  277. if (! psf->fdata)
  278. return 0 ;
  279. pima = (IMA_ADPCM_PRIVATE*) psf->fdata ;
  280. if (! (psf->blockwidth && psf->datalength && psf->dataoffset))
  281. { psf->error = SFE_BAD_SEEK ;
  282. return ((off_t) -1) ;
  283. } ;
  284. switch (whence)
  285. { case SEEK_SET :
  286. if (offset < 0 || offset > pima->blocks * pima->samplesperblock)
  287. { psf->error = SFE_BAD_SEEK ;
  288. return ((off_t) -1) ;
  289. } ;
  290. newblock  = offset / pima->samplesperblock ;
  291. newsample = offset % pima->samplesperblock ;
  292. break ;
  293. case SEEK_CUR :
  294. if (psf->current + offset < 0 || psf->current + offset > pima->blocks * pima->samplesperblock)
  295. { psf->error = SFE_BAD_SEEK ;
  296. return ((off_t) -1) ;
  297. } ;
  298. newblock  = (psf->current + offset) / pima->samplesperblock ;
  299. newsample = (psf->current + offset) % pima->samplesperblock ;
  300. break ;
  301. case SEEK_END :
  302. if (offset > 0 || pima->samplesperblock * pima->blocks + offset < 0)
  303. { psf->error = SFE_BAD_SEEK ;
  304. return ((off_t) -1) ;
  305. } ;
  306. newblock  = (pima->samplesperblock * pima->blocks + offset) / pima->samplesperblock ;
  307. newsample = (pima->samplesperblock * pima->blocks + offset) % pima->samplesperblock ;
  308. break ;
  309. default : 
  310. psf->error = SFE_BAD_SEEK ;
  311. return ((off_t) -1) ;
  312. } ;
  313. if (psf->mode == SF_MODE_READ)
  314. { fseek (psf->file, (int) (psf->dataoffset + newblock * pima->blocksize), SEEK_SET) ;
  315. pima->blockcount  = newblock ;
  316. ima_read_block (psf, pima) ;
  317. pima->samplecount = newsample ;
  318. }
  319. else
  320. { /* What to do about write??? */ 
  321. psf->error = SFE_BAD_SEEK ;
  322. return ((off_t) -1) ;
  323. } ;
  324. psf->current = newblock * pima->samplesperblock + newsample ;
  325. return psf->current ;
  326. } /* ima_seek */
  327. /*==========================================================================================
  328. ** IMA ADPCM Write Functions.
  329. */
  330. int wav_ima_writer_init (SF_PRIVATE *psf, WAV_FMT *fmt)
  331. { IMA_ADPCM_PUBLIC  public ;
  332. int error ;
  333. if (fmt->format != 0x0011)
  334. psf_sprintf (psf, "*** Warning : format tag != WAVE_FORMAT_IMA_ADPCM.n") ;
  335. public.blocksize = wav_srate2blocksize (fmt->ima.samplerate) ;
  336. public.channels  = psf->sf.channels ;
  337. public.samplesperblock = 2 * (public.blocksize - 4 * psf->sf.channels) / psf->sf.channels + 1 ;
  338. if ((error = ima_writer_init (psf, &public)))
  339. return error ;
  340. fmt->ima.blockalign      = public.blocksize ;
  341. fmt->ima.bitwidth        = 4 ;
  342. fmt->ima.extrabytes      = 2 ;
  343. fmt->ima.samplesperblock = public.samplesperblock ;
  344. fmt->ima.bytespersec     = (fmt->ima.samplerate * fmt->ima.blockalign) / fmt->ima.samplesperblock ;
  345. return 0 ;
  346. } /* wav_ima_writer_init */
  347. /*==========================================================================================
  348. */
  349. static
  350. int ima_write_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima)
  351. { int chan, k, step, diff, vpdiff, blockindex, index, indexstart ;
  352. short bytecode, mask ;
  353. /* Write the block header. */
  354. for (chan = 0 ; chan < pima->channels ; chan++)
  355. { pima->block [chan*4]   = pima->samples [chan] & 0xFF ;
  356. pima->block [chan*4+1] = (pima->samples [chan] >> 8) & 0xFF ;
  357. pima->block [chan*4+2] = pima->stepindex [chan] ;
  358. pima->block [chan*4+3] = 0 ;
  359. } ;
  360. pima->previous  [0] = pima->samples [0] ;
  361. pima->previous  [1] = pima->samples [1] ;
  362. /* Encode the samples as 4 bit. */
  363. for (k = pima->channels ; k < (pima->samplesperblock * pima->channels) ; k ++)
  364. { chan = (pima->channels > 1) ? (k % 2) : 0 ;
  365. diff = pima->samples [k] - pima->previous [chan] ;
  366. bytecode = 0 ;
  367. step = ima_step_size [pima->stepindex [chan]] ;
  368. vpdiff = step >> 3 ;
  369. if (diff < 0) 
  370. { bytecode = 8 ; 
  371. diff = -diff ;
  372. } ;
  373. mask = 4 ;
  374. while (mask)
  375. { if (diff >= step)
  376. { bytecode |= mask ;
  377. diff -= step ;
  378. vpdiff += step ;
  379. } ;
  380. step >>= 1 ;
  381. mask >>= 1 ;
  382. } ;
  383. if (bytecode & 8)
  384. pima->previous [chan] -= vpdiff ;
  385. else
  386. pima->previous [chan] += vpdiff ;
  387. if (pima->previous [chan] > 32767) 
  388. pima->previous [chan] = 32767;
  389. else if (pima->previous [chan] < -32768) 
  390. pima->previous [chan] = -32768;
  391. pima->stepindex [chan] += ima_index_adjust [bytecode] ;
  392. if (pima->stepindex [chan] < 0)
  393. pima->stepindex [chan] = 0 ;
  394. else if (pima->stepindex [chan] > 88)
  395. pima->stepindex [chan] = 88 ;
  396. pima->samples [k] = bytecode ;
  397. } ;
  398. /* Pack the 4 bit encoded samples. */
  399. blockindex = 4 * pima->channels ;
  400. indexstart = pima->channels ;
  401. while (blockindex <  pima->blocksize)
  402. { for (chan = 0 ; chan < pima->channels ; chan++)
  403. { index = indexstart + chan ;
  404. for (k = 0 ; k < 4 ; k++)
  405. { pima->block [blockindex] = pima->samples [index] & 0x0F ;
  406. index += pima->channels ;
  407. pima->block [blockindex] |= (pima->samples [index] << 4) & 0xF0 ;
  408. index += pima->channels ;
  409. blockindex ++ ;
  410. } ;
  411. } ;
  412. indexstart += 8 * pima->channels ;
  413. } ;
  414. /* Write the block to disk. */
  415. if ((k = fwrite (pima->block, 1, pima->blocksize, psf->file)) != pima->blocksize)
  416. psf_sprintf (psf, "*** Warning : short write (%d != %d).n", k, pima->blocksize) ;
  417. memset (pima->samples, 0, pima->samplesperblock * sizeof (short)) ;
  418. pima->samplecount = 0 ;
  419. return 1 ;
  420. } /* ima_write_block */
  421. static
  422. int ima_write (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima, short *ptr, int len)
  423. { int count, total = 0, index = 0 ;
  424. while (index < len)
  425. { count = (pima->samplesperblock - pima->samplecount) * pima->channels ;
  426. if (count > len - index)
  427. count = len - index ;
  428. memcpy (&(pima->samples [pima->samplecount * pima->channels]), &(ptr [index]), count * sizeof (short)) ;
  429. index += count ;
  430. pima->samplecount += count / pima->channels ;
  431. total = index ;
  432. if (pima->samplecount >= pima->samplesperblock)
  433. ima_write_block (psf, pima) ;
  434. } ;
  435. return total ;
  436. } /* ima_write */
  437. int ima_write_s (SF_PRIVATE *psf, short *ptr, int len)
  438. { IMA_ADPCM_PRIVATE  *pima ; 
  439. int total ;
  440. if (! psf->fdata)
  441. return 0 ;
  442. pima = (IMA_ADPCM_PRIVATE*) psf->fdata ;
  443. total = ima_write (psf, pima, ptr, len) ;
  444. return total ;
  445. } /* ima_write_s */
  446. int ima_write_i  (SF_PRIVATE *psf, int *ptr, int len)
  447. { IMA_ADPCM_PRIVATE *pima ; 
  448. short *sptr ;
  449. int k, bufferlen, writecount = 0, count ;
  450. int index = 0, total = 0 ;
  451. if (! psf->fdata)
  452. return 0 ;
  453. pima = (IMA_ADPCM_PRIVATE*) psf->fdata ;
  454. sptr = (short*) psf->buffer ;
  455. bufferlen = ((SF_BUFFER_LEN / psf->blockwidth) * psf->blockwidth) / sizeof (short) ;
  456. while (len > 0)
  457. { writecount = (len >= bufferlen) ? bufferlen : len ;
  458. for (k = 0 ; k < writecount ; k++)
  459. sptr [k] = (short) ptr [index+k] ;
  460. count = ima_write (psf, pima, sptr, writecount) ;
  461. index += writecount ;
  462. total += count ;
  463. len -= writecount ;
  464. } ;
  465. return total ;
  466. } /* ima_write_i */
  467. int ima_write_d  (SF_PRIVATE *psf, double *ptr, int len, int normalize)
  468. { IMA_ADPCM_PRIVATE *pima ; 
  469. short *sptr ;
  470. int k, bufferlen, writecount = 0, count ;
  471. int index = 0, total = 0 ;
  472. double  normfact ;
  473. normfact = (normalize ? ((double) 0x8000) : 1.0) ;
  474. if (! psf->fdata)
  475. return 0 ;
  476. pima = (IMA_ADPCM_PRIVATE*) psf->fdata ;
  477. sptr = (short*) psf->buffer ;
  478. bufferlen = ((SF_BUFFER_LEN / psf->blockwidth) * psf->blockwidth) / sizeof (short) ;
  479. while (len > 0)
  480. { writecount = (len >= bufferlen) ? bufferlen : len ;
  481. for (k = 0 ; k < writecount ; k++)
  482. sptr [k] = (short) (normfact * ptr [index+k])  ;
  483. count = ima_write (psf, pima, sptr, writecount) ;
  484. index += writecount ;
  485. total += count ;
  486. len -= writecount ;
  487. } ;
  488. return total ;
  489. } /* ima_write_d */
  490. int wav_ima_close (SF_PRIVATE  *psf)
  491. { IMA_ADPCM_PRIVATE *pima ; 
  492. unsigned int dword ;
  493. if (! psf->fdata)
  494. return wav_close (psf) ;
  495. pima = (IMA_ADPCM_PRIVATE*) psf->fdata ;
  496. if (psf->mode == SF_MODE_WRITE)
  497. { /* If a block has been partially assembled, write it out
  498. ** as the final block.
  499. */
  500. if (pima->samplecount && pima->samplecount < pima->samplesperblock)
  501. ima_write_block (psf, pima) ;
  502. /*  Now we know for certain the length of the file we can
  503. **  re-write correct values for the RIFF and data chunks.
  504. */
  505.  
  506. fseek (psf->file, 0, SEEK_END) ;
  507. psf->filelength = ftell (psf->file) ;
  508. /* Fix RIFF size. */
  509. dword = H2LE_INT (psf->filelength - 2 * sizeof (dword)) ;
  510. fseek (psf->file, sizeof (dword), SEEK_SET) ;
  511. fwrite (&dword, sizeof (dword), 1, psf->file) ;
  512. psf->datalength = psf->filelength - psf->dataoffset ;
  513. fseek (psf->file, (int) (psf->dataoffset - sizeof (dword)), SEEK_SET) ;
  514. dword = H2LE_INT (psf->datalength) ;
  515. fwrite (&dword, sizeof (dword), 1, psf->file) ;
  516. } ;
  517. if (psf->fdata)
  518. free (psf->fdata) ;
  519. psf->fdata = NULL ;
  520. return 0 ;
  521. } /* wav_ima_close */
  522. static
  523. unsigned int wav_srate2blocksize (unsigned int srate)
  524. { if (srate < 12000)
  525. return 256 ;
  526. if (srate < 23000)
  527. return 512 ;
  528. return 1024 ;
  529. } /* wav_srate2blocksize */