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

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 <string.h>
  22. #include <math.h>
  23. #include "sndfile.h"
  24. #include "sfendian.h"
  25. #include "common.h"
  26. #include "wav_w64.h"
  27. #include "GSM610/gsm.h"
  28. #define GSM610_BLOCKSIZE 33
  29. #define GSM610_SAMPLES 160
  30. typedef struct gsm610_tag
  31. { int blocks ;
  32. int blockcount, samplecount ;
  33. int samplesperblock, blocksize ;
  34. int (*decode_block) (SF_PRIVATE *psf, struct gsm610_tag *pgsm610) ;
  35. int (*encode_block) (SF_PRIVATE *psf, struct gsm610_tag *pgsm610) ;
  36. short samples [WAV_W64_GSM610_SAMPLES] ;
  37. unsigned char block [WAV_W64_GSM610_BLOCKSIZE] ;
  38. /* Damn I hate typedef-ed pointers; yes, gsm is a pointer type. */
  39. gsm gsm_data ;
  40. } GSM610_PRIVATE ;
  41. static sf_count_t gsm610_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
  42. static sf_count_t gsm610_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
  43. static sf_count_t gsm610_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
  44. static sf_count_t gsm610_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
  45. static sf_count_t gsm610_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
  46. static sf_count_t gsm610_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
  47. static sf_count_t gsm610_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
  48. static sf_count_t gsm610_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
  49. static int gsm610_read_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610, short *ptr, int len) ;
  50. static int gsm610_write_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610, const short *ptr, int len) ;
  51. static int gsm610_decode_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610) ;
  52. static int gsm610_encode_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610) ;
  53. static int gsm610_wav_decode_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610) ;
  54. static int gsm610_wav_encode_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610) ;
  55. static sf_count_t gsm610_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
  56. static int gsm610_close (SF_PRIVATE *psf) ;
  57. /*============================================================================================
  58. ** WAV GSM610 initialisation function.
  59. */
  60. int
  61. gsm610_init (SF_PRIVATE *psf)
  62. { GSM610_PRIVATE *pgsm610 ;
  63. int true_flag = 1 ;
  64. if (psf->codec_data != NULL)
  65. { psf_log_printf (psf, "*** psf->codec_data is not NULL.n") ;
  66. return SFE_INTERNAL ;
  67. } ;
  68. if (psf->file.mode == SFM_RDWR)
  69. return SFE_BAD_MODE_RW ;
  70. psf->sf.seekable = SF_FALSE ;
  71. if ((pgsm610 = calloc (1, sizeof (GSM610_PRIVATE))) == NULL)
  72. return SFE_MALLOC_FAILED ;
  73. psf->codec_data = pgsm610 ;
  74. memset (pgsm610, 0, sizeof (GSM610_PRIVATE)) ;
  75. /*============================================================
  76. Need separate gsm_data structs for encode and decode.
  77. ============================================================*/
  78. if ((pgsm610->gsm_data = gsm_create ()) == NULL)
  79. return SFE_MALLOC_FAILED ;
  80. switch (SF_CONTAINER (psf->sf.format))
  81. { case SF_FORMAT_WAV :
  82. case SF_FORMAT_WAVEX :
  83. case SF_FORMAT_W64 :
  84. gsm_option (pgsm610->gsm_data, GSM_OPT_WAV49, &true_flag) ;
  85. pgsm610->encode_block = gsm610_wav_encode_block ;
  86. pgsm610->decode_block = gsm610_wav_decode_block ;
  87. pgsm610->samplesperblock = WAV_W64_GSM610_SAMPLES ;
  88. pgsm610->blocksize = WAV_W64_GSM610_BLOCKSIZE ;
  89. break ;
  90. case SF_FORMAT_AIFF :
  91. case SF_FORMAT_RAW :
  92. pgsm610->encode_block = gsm610_encode_block ;
  93. pgsm610->decode_block = gsm610_decode_block ;
  94. pgsm610->samplesperblock = GSM610_SAMPLES ;
  95. pgsm610->blocksize = GSM610_BLOCKSIZE ;
  96. break ;
  97. default :
  98. return SFE_INTERNAL ;
  99. break ;
  100. } ;
  101. if (psf->file.mode == SFM_READ)
  102. { if (psf->datalength % pgsm610->blocksize == 0)
  103. pgsm610->blocks = psf->datalength / pgsm610->blocksize ;
  104. else if (psf->datalength % pgsm610->blocksize == 1 && pgsm610->blocksize == GSM610_BLOCKSIZE)
  105. { /*
  106. ** Weird AIFF specific case.
  107. ** AIFF chunks must be at an even offset from the start of file and
  108. ** GSM610_BLOCKSIZE is odd which can result in an odd length SSND
  109. ** chunk. The SSND chunk then gets padded on write which means that
  110. ** when it is read the datalength is too big by 1.
  111. */
  112. pgsm610->blocks = psf->datalength / pgsm610->blocksize ;
  113. }
  114. else
  115. { psf_log_printf (psf, "*** Warning : data chunk seems to be truncated.n") ;
  116. pgsm610->blocks = psf->datalength / pgsm610->blocksize + 1 ;
  117. } ;
  118. psf->sf.frames = pgsm610->samplesperblock * pgsm610->blocks ;
  119. psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
  120. pgsm610->decode_block (psf, pgsm610) ; /* Read first block. */
  121. psf->read_short = gsm610_read_s ;
  122. psf->read_int = gsm610_read_i ;
  123. psf->read_float = gsm610_read_f ;
  124. psf->read_double = gsm610_read_d ;
  125. } ;
  126. if (psf->file.mode == SFM_WRITE)
  127. { pgsm610->blockcount = 0 ;
  128. pgsm610->samplecount = 0 ;
  129. psf->write_short = gsm610_write_s ;
  130. psf->write_int = gsm610_write_i ;
  131. psf->write_float = gsm610_write_f ;
  132. psf->write_double = gsm610_write_d ;
  133. } ;
  134. psf->codec_close = gsm610_close ;
  135. psf->seek = gsm610_seek ;
  136. psf->filelength = psf_get_filelen (psf) ;
  137. psf->datalength = psf->filelength - psf->dataoffset ;
  138. return 0 ;
  139. } /* gsm610_init */
  140. /*============================================================================================
  141. ** GSM 6.10 Read Functions.
  142. */
  143. static int
  144. gsm610_wav_decode_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610)
  145. { int k ;
  146. pgsm610->blockcount ++ ;
  147. pgsm610->samplecount = 0 ;
  148. if (pgsm610->blockcount > pgsm610->blocks)
  149. { memset (pgsm610->samples, 0, WAV_W64_GSM610_SAMPLES * sizeof (short)) ;
  150. return 1 ;
  151. } ;
  152. if ((k = psf_fread (pgsm610->block, 1, WAV_W64_GSM610_BLOCKSIZE, psf)) != WAV_W64_GSM610_BLOCKSIZE)
  153. psf_log_printf (psf, "*** Warning : short read (%d != %d).n", k, WAV_W64_GSM610_BLOCKSIZE) ;
  154. if (gsm_decode (pgsm610->gsm_data, pgsm610->block, pgsm610->samples) < 0)
  155. { psf_log_printf (psf, "Error from WAV gsm_decode() on frame : %dn", pgsm610->blockcount) ;
  156. return 0 ;
  157. } ;
  158. if (gsm_decode (pgsm610->gsm_data, pgsm610->block + (WAV_W64_GSM610_BLOCKSIZE + 1) / 2, pgsm610->samples + WAV_W64_GSM610_SAMPLES / 2) < 0)
  159. { psf_log_printf (psf, "Error from WAV gsm_decode() on frame : %d.5n", pgsm610->blockcount) ;
  160. return 0 ;
  161. } ;
  162. return 1 ;
  163. } /* gsm610_wav_decode_block */
  164. static int
  165. gsm610_decode_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610)
  166. { int k ;
  167. pgsm610->blockcount ++ ;
  168. pgsm610->samplecount = 0 ;
  169. if (pgsm610->blockcount > pgsm610->blocks)
  170. { memset (pgsm610->samples, 0, GSM610_SAMPLES * sizeof (short)) ;
  171. return 1 ;
  172. } ;
  173. if ((k = psf_fread (pgsm610->block, 1, GSM610_BLOCKSIZE, psf)) != GSM610_BLOCKSIZE)
  174. psf_log_printf (psf, "*** Warning : short read (%d != %d).n", k, GSM610_BLOCKSIZE) ;
  175. if (gsm_decode (pgsm610->gsm_data, pgsm610->block, pgsm610->samples) < 0)
  176. { psf_log_printf (psf, "Error from standard gsm_decode() on frame : %dn", pgsm610->blockcount) ;
  177. return 0 ;
  178. } ;
  179. return 1 ;
  180. } /* gsm610_decode_block */
  181. static int
  182. gsm610_read_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610, short *ptr, int len)
  183. { int count, total = 0, indx = 0 ;
  184. while (indx < len)
  185. { if (pgsm610->blockcount >= pgsm610->blocks && pgsm610->samplecount >= pgsm610->samplesperblock)
  186. { memset (&(ptr [indx]), 0, (len - indx) * sizeof (short)) ;
  187. return total ;
  188. } ;
  189. if (pgsm610->samplecount >= pgsm610->samplesperblock)
  190. pgsm610->decode_block (psf, pgsm610) ;
  191. count = pgsm610->samplesperblock - pgsm610->samplecount ;
  192. count = (len - indx > count) ? count : len - indx ;
  193. memcpy (&(ptr [indx]), &(pgsm610->samples [pgsm610->samplecount]), count * sizeof (short)) ;
  194. indx += count ;
  195. pgsm610->samplecount += count ;
  196. total = indx ;
  197. } ;
  198. return total ;
  199. } /* gsm610_read_block */
  200. static sf_count_t
  201. gsm610_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
  202. { GSM610_PRIVATE  *pgsm610 ;
  203. int readcount, count ;
  204. sf_count_t total = 0 ;
  205. if (psf->codec_data == NULL)
  206. return 0 ;
  207. pgsm610 = (GSM610_PRIVATE*) psf->codec_data ;
  208. while (len > 0)
  209. { readcount = (len > 0x10000000) ? 0x1000000 : (int) len ;
  210. count = gsm610_read_block (psf, pgsm610, ptr, readcount) ;
  211. total += count ;
  212. len -= count ;
  213. if (count != readcount)
  214. break ;
  215. } ;
  216. return total ;
  217. } /* gsm610_read_s */
  218. static sf_count_t
  219. gsm610_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
  220. { GSM610_PRIVATE *pgsm610 ;
  221. short *sptr ;
  222. int k, bufferlen, readcount = 0, count ;
  223. sf_count_t total = 0 ;
  224. if (psf->codec_data == NULL)
  225. return 0 ;
  226. pgsm610 = (GSM610_PRIVATE*) psf->codec_data ;
  227. sptr = psf->u.sbuf ;
  228. bufferlen = ARRAY_LEN (psf->u.sbuf) ;
  229. while (len > 0)
  230. { readcount = (len >= bufferlen) ? bufferlen : len ;
  231. count = gsm610_read_block (psf, pgsm610, sptr, readcount) ;
  232. for (k = 0 ; k < readcount ; k++)
  233. ptr [total + k] = sptr [k] << 16 ;
  234. total += count ;
  235. len -= readcount ;
  236. } ;
  237. return total ;
  238. } /* gsm610_read_i */
  239. static sf_count_t
  240. gsm610_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
  241. { GSM610_PRIVATE *pgsm610 ;
  242. short *sptr ;
  243. int k, bufferlen, readcount = 0, count ;
  244. sf_count_t total = 0 ;
  245. float normfact ;
  246. if (psf->codec_data == NULL)
  247. return 0 ;
  248. pgsm610 = (GSM610_PRIVATE*) psf->codec_data ;
  249. normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x8000) : 1.0 ;
  250. sptr = psf->u.sbuf ;
  251. bufferlen = ARRAY_LEN (psf->u.sbuf) ;
  252. while (len > 0)
  253. { readcount = (len >= bufferlen) ? bufferlen : len ;
  254. count = gsm610_read_block (psf, pgsm610, sptr, readcount) ;
  255. for (k = 0 ; k < readcount ; k++)
  256. ptr [total + k] = normfact * sptr [k] ;
  257. total += count ;
  258. len -= readcount ;
  259. } ;
  260. return total ;
  261. } /* gsm610_read_f */
  262. static sf_count_t
  263. gsm610_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
  264. { GSM610_PRIVATE *pgsm610 ;
  265. short *sptr ;
  266. int k, bufferlen, readcount = 0, count ;
  267. sf_count_t total = 0 ;
  268. double normfact ;
  269. normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x8000) : 1.0 ;
  270. if (psf->codec_data == NULL)
  271. return 0 ;
  272. pgsm610 = (GSM610_PRIVATE*) psf->codec_data ;
  273. sptr = psf->u.sbuf ;
  274. bufferlen = ARRAY_LEN (psf->u.sbuf) ;
  275. while (len > 0)
  276. { readcount = (len >= bufferlen) ? bufferlen : len ;
  277. count = gsm610_read_block (psf, pgsm610, sptr, readcount) ;
  278. for (k = 0 ; k < readcount ; k++)
  279. ptr [total + k] = normfact * sptr [k] ;
  280. total += count ;
  281. len -= readcount ;
  282. } ;
  283. return total ;
  284. } /* gsm610_read_d */
  285. static sf_count_t
  286. gsm610_seek (SF_PRIVATE *psf, int UNUSED (mode), sf_count_t offset)
  287. { GSM610_PRIVATE *pgsm610 ;
  288. int newblock, newsample ;
  289. if (psf->codec_data == NULL)
  290. return 0 ;
  291. pgsm610 = (GSM610_PRIVATE*) psf->codec_data ;
  292. if (psf->dataoffset < 0)
  293. { psf->error = SFE_BAD_SEEK ;
  294. return PSF_SEEK_ERROR ;
  295. } ;
  296. if (offset == 0)
  297. { int true_flag = 1 ;
  298. psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
  299. pgsm610->blockcount = 0 ;
  300. gsm_init (pgsm610->gsm_data) ;
  301. if ((SF_CONTAINER (psf->sf.format)) == SF_FORMAT_WAV ||
  302. (SF_CONTAINER (psf->sf.format)) == SF_FORMAT_W64)
  303. gsm_option (pgsm610->gsm_data, GSM_OPT_WAV49, &true_flag) ;
  304. pgsm610->decode_block (psf, pgsm610) ;
  305. pgsm610->samplecount = 0 ;
  306. return 0 ;
  307. } ;
  308. if (offset < 0 || offset > pgsm610->blocks * pgsm610->samplesperblock)
  309. { psf->error = SFE_BAD_SEEK ;
  310. return PSF_SEEK_ERROR ;
  311. } ;
  312. newblock = offset / pgsm610->samplesperblock ;
  313. newsample = offset % pgsm610->samplesperblock ;
  314. if (psf->file.mode == SFM_READ)
  315. { if (psf->read_current != newblock * pgsm610->samplesperblock + newsample)
  316. { psf_fseek (psf, psf->dataoffset + newblock * pgsm610->samplesperblock, SEEK_SET) ;
  317. pgsm610->blockcount = newblock ;
  318. pgsm610->decode_block (psf, pgsm610) ;
  319. pgsm610->samplecount = newsample ;
  320. } ;
  321. return newblock * pgsm610->samplesperblock + newsample ;
  322. } ;
  323. /* What to do about write??? */
  324. psf->error = SFE_BAD_SEEK ;
  325. return PSF_SEEK_ERROR ;
  326. } /* gsm610_seek */
  327. /*==========================================================================================
  328. ** GSM 6.10 Write Functions.
  329. */
  330. static int
  331. gsm610_encode_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610)
  332. { int k ;
  333. /* Encode the samples. */
  334. gsm_encode (pgsm610->gsm_data, pgsm610->samples, pgsm610->block) ;
  335. /* Write the block to disk. */
  336. if ((k = psf_fwrite (pgsm610->block, 1, GSM610_BLOCKSIZE, psf)) != GSM610_BLOCKSIZE)
  337. psf_log_printf (psf, "*** Warning : short write (%d != %d).n", k, GSM610_BLOCKSIZE) ;
  338. pgsm610->samplecount = 0 ;
  339. pgsm610->blockcount ++ ;
  340. /* Set samples to zero for next block. */
  341. memset (pgsm610->samples, 0, WAV_W64_GSM610_SAMPLES * sizeof (short)) ;
  342. return 1 ;
  343. } /* gsm610_encode_block */
  344. static int
  345. gsm610_wav_encode_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610)
  346. { int k ;
  347. /* Encode the samples. */
  348. gsm_encode (pgsm610->gsm_data, pgsm610->samples, pgsm610->block) ;
  349. gsm_encode (pgsm610->gsm_data, pgsm610->samples+WAV_W64_GSM610_SAMPLES/2, pgsm610->block+WAV_W64_GSM610_BLOCKSIZE/2) ;
  350. /* Write the block to disk. */
  351. if ((k = psf_fwrite (pgsm610->block, 1, WAV_W64_GSM610_BLOCKSIZE, psf)) != WAV_W64_GSM610_BLOCKSIZE)
  352. psf_log_printf (psf, "*** Warning : short write (%d != %d).n", k, WAV_W64_GSM610_BLOCKSIZE) ;
  353. pgsm610->samplecount = 0 ;
  354. pgsm610->blockcount ++ ;
  355. /* Set samples to zero for next block. */
  356. memset (pgsm610->samples, 0, WAV_W64_GSM610_SAMPLES * sizeof (short)) ;
  357. return 1 ;
  358. } /* gsm610_wav_encode_block */
  359. static int
  360. gsm610_write_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610, const short *ptr, int len)
  361. { int count, total = 0, indx = 0 ;
  362. while (indx < len)
  363. { count = pgsm610->samplesperblock - pgsm610->samplecount ;
  364. if (count > len - indx)
  365. count = len - indx ;
  366. memcpy (&(pgsm610->samples [pgsm610->samplecount]), &(ptr [indx]), count * sizeof (short)) ;
  367. indx += count ;
  368. pgsm610->samplecount += count ;
  369. total = indx ;
  370. if (pgsm610->samplecount >= pgsm610->samplesperblock)
  371. pgsm610->encode_block (psf, pgsm610) ;
  372. } ;
  373. return total ;
  374. } /* gsm610_write_block */
  375. static sf_count_t
  376. gsm610_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
  377. { GSM610_PRIVATE  *pgsm610 ;
  378. int writecount, count ;
  379. sf_count_t total = 0 ;
  380. if (psf->codec_data == NULL)
  381. return 0 ;
  382. pgsm610 = (GSM610_PRIVATE*) psf->codec_data ;
  383. while (len > 0)
  384. { writecount = (len > 0x10000000) ? 0x10000000 : (int) len ;
  385. count = gsm610_write_block (psf, pgsm610, ptr, writecount) ;
  386. total += count ;
  387. len -= count ;
  388. if (count != writecount)
  389. break ;
  390. } ;
  391. return total ;
  392. } /* gsm610_write_s */
  393. static sf_count_t
  394. gsm610_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
  395. { GSM610_PRIVATE *pgsm610 ;
  396. short *sptr ;
  397. int k, bufferlen, writecount = 0, count ;
  398. sf_count_t total = 0 ;
  399. if (psf->codec_data == NULL)
  400. return 0 ;
  401. pgsm610 = (GSM610_PRIVATE*) psf->codec_data ;
  402. sptr = psf->u.sbuf ;
  403. bufferlen = ARRAY_LEN (psf->u.sbuf) ;
  404. while (len > 0)
  405. { writecount = (len >= bufferlen) ? bufferlen : len ;
  406. for (k = 0 ; k < writecount ; k++)
  407. sptr [k] = ptr [total + k] >> 16 ;
  408. count = gsm610_write_block (psf, pgsm610, sptr, writecount) ;
  409. total += count ;
  410. len -= writecount ;
  411. } ;
  412. return total ;
  413. } /* gsm610_write_i */
  414. static sf_count_t
  415. gsm610_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
  416. { GSM610_PRIVATE *pgsm610 ;
  417. short *sptr ;
  418. int k, bufferlen, writecount = 0, count ;
  419. sf_count_t total = 0 ;
  420. float normfact ;
  421. if (psf->codec_data == NULL)
  422. return 0 ;
  423. pgsm610 = (GSM610_PRIVATE*) psf->codec_data ;
  424. normfact = (psf->norm_float == SF_TRUE) ? (1.0 * 0x7FFF) : 1.0 ;
  425. sptr = psf->u.sbuf ;
  426. bufferlen = ARRAY_LEN (psf->u.sbuf) ;
  427. while (len > 0)
  428. { writecount = (len >= bufferlen) ? bufferlen : len ;
  429. for (k = 0 ; k < writecount ; k++)
  430. sptr [k] = lrintf (normfact * ptr [total + k]) ;
  431. count = gsm610_write_block (psf, pgsm610, sptr, writecount) ;
  432. total += count ;
  433. len -= writecount ;
  434. } ;
  435. return total ;
  436. } /* gsm610_write_f */
  437. static sf_count_t
  438. gsm610_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
  439. { GSM610_PRIVATE *pgsm610 ;
  440. short *sptr ;
  441. int k, bufferlen, writecount = 0, count ;
  442. sf_count_t total = 0 ;
  443. double normfact ;
  444. if (psf->codec_data == NULL)
  445. return 0 ;
  446. pgsm610 = (GSM610_PRIVATE*) psf->codec_data ;
  447. normfact = (psf->norm_double == SF_TRUE) ? (1.0 * 0x7FFF) : 1.0 ;
  448. sptr = psf->u.sbuf ;
  449. bufferlen = ARRAY_LEN (psf->u.sbuf) ;
  450. while (len > 0)
  451. { writecount = (len >= bufferlen) ? bufferlen : len ;
  452. for (k = 0 ; k < writecount ; k++)
  453. sptr [k] = lrint (normfact * ptr [total + k]) ;
  454. count = gsm610_write_block (psf, pgsm610, sptr, writecount) ;
  455. total += count ;
  456. len -= writecount ;
  457. } ;
  458. return total ;
  459. } /* gsm610_write_d */
  460. static int
  461. gsm610_close (SF_PRIVATE *psf)
  462. { GSM610_PRIVATE *pgsm610 ;
  463. if (psf->codec_data == NULL)
  464. return 0 ;
  465. pgsm610 = (GSM610_PRIVATE*) psf->codec_data ;
  466. if (psf->file.mode == SFM_WRITE)
  467. { /* If a block has been partially assembled, write it out
  468. ** as the final block.
  469. */
  470. if (pgsm610->samplecount && pgsm610->samplecount < pgsm610->samplesperblock)
  471. pgsm610->encode_block (psf, pgsm610) ;
  472. } ;
  473. if (pgsm610->gsm_data)
  474. gsm_destroy (pgsm610->gsm_data) ;
  475. return 0 ;
  476. } /* gsm610_close */