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

流媒体/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. #include "GSM610/gsm.h"
  28. #define GSM610_BLOCKSIZE 65
  29. #define GSM610_SAMPLES 320
  30. typedef struct
  31. { unsigned int blocks ; 
  32. int blockcount, samplecount ;
  33. unsigned char block [GSM610_BLOCKSIZE] ;
  34. short samples [GSM610_SAMPLES] ;
  35. gsm gsm_data ;
  36. } GSM610_PRIVATE ;
  37. static int wav_gsm610_read_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610) ;
  38. static int wav_gsm610_read (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610, short *ptr, int len) ;
  39. static int wav_gsm610_write_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610) ;
  40. static int wav_gsm610_write (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610, short *ptr, int len) ;
  41. /*============================================================================================
  42. ** WAV GSM610 Reader initialisation function.
  43. */
  44. int wav_gsm610_reader_init (SF_PRIVATE *psf, WAV_FMT *fmt)
  45. { GSM610_PRIVATE *pgsm610 ;
  46. int  true = 1 ;
  47. psf->sf.seekable = SF_FALSE ;
  48. if (psf->mode != SF_MODE_READ)
  49. return SFE_BAD_MODE_RW ;
  50. if (! (pgsm610 = malloc (sizeof (GSM610_PRIVATE))))
  51. return SFE_MALLOC_FAILED ;
  52. psf->fdata = (void*) pgsm610 ;
  53. memset (pgsm610, 0, sizeof (GSM610_PRIVATE)) ;
  54. if (! (pgsm610->gsm_data = gsm_create ()))
  55. return SFE_MALLOC_FAILED ;
  56. gsm_option (pgsm610->gsm_data,  GSM_OPT_WAV49, &true) ;
  57. if (psf->datalength % GSM610_BLOCKSIZE)
  58. { psf_sprintf (psf, "*** Warning : data chunk seems to be truncated.n") ;
  59. pgsm610->blocks = psf->datalength / GSM610_BLOCKSIZE + 1 ;
  60. }
  61. else
  62. pgsm610->blocks = psf->datalength / GSM610_BLOCKSIZE ;
  63. psf->sf.samples = GSM610_SAMPLES * pgsm610->blocks ;
  64. wav_gsm610_read_block (psf, pgsm610) ; /* Read first block. */
  65. return 0 ;
  66. } /* wav_gsm610_reader_init */
  67. /*============================================================================================
  68. ** WAV GSM610 writer initialisation function.
  69. */
  70. int wav_gsm610_writer_init (SF_PRIVATE *psf, WAV_FMT *fmt)
  71. { GSM610_PRIVATE *pgsm610 ;
  72. int  true = 1 ;
  73. if (fmt->format != 0x0031)
  74. psf_sprintf (psf, "*** Warning : format tag != WAVE_FORMAT_GSM610.n") ;
  75. if (psf->mode != SF_MODE_WRITE)
  76. return SFE_BAD_MODE_RW ;
  77. if (! (pgsm610 = malloc (sizeof (GSM610_PRIVATE))))
  78. return SFE_MALLOC_FAILED ;
  79. psf->fdata = (void*) pgsm610 ;
  80. memset (pgsm610, 0, sizeof (GSM610_PRIVATE)) ;
  81. if (! (pgsm610->gsm_data = gsm_create ()))
  82. return SFE_MALLOC_FAILED ;
  83. gsm_option (pgsm610->gsm_data,  GSM_OPT_WAV49, &true) ;
  84. pgsm610->blockcount  = 0 ;
  85. pgsm610->samplecount = 0 ;
  86. fmt->gsm610.blockalign      = GSM610_BLOCKSIZE ;
  87. fmt->gsm610.bitwidth        = 0 ;
  88. fmt->gsm610.extrabytes      = 2 ;
  89. fmt->gsm610.samplesperblock = GSM610_SAMPLES ;
  90. fmt->gsm610.bytespersec     = fmt->gsm610.samplerate * GSM610_BLOCKSIZE / GSM610_SAMPLES ;
  91. if (fmt->gsm610.bytespersec * GSM610_SAMPLES / GSM610_BLOCKSIZE < fmt->gsm610.samplerate) 
  92. fmt->gsm610.bytespersec ++ ;
  93. return 0 ;
  94. } /* wav_gsm610_writer_init */
  95. /*============================================================================================
  96. ** GSM 6.10 Read Functions.
  97. */
  98. static
  99. int wav_gsm610_read_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610)
  100. { int k ;
  101. pgsm610->blockcount ++ ;
  102. pgsm610->samplecount = 0 ;
  103. if (pgsm610->blockcount > pgsm610->blocks)
  104. { memset (pgsm610->samples, 0, GSM610_SAMPLES * sizeof (short)) ;
  105. return 1 ;
  106. } ;
  107. if ((k = fread (pgsm610->block, 1, GSM610_BLOCKSIZE, psf->file)) != GSM610_BLOCKSIZE)
  108. psf_sprintf (psf, "*** Warning : short read (%d != %d).n", k, GSM610_BLOCKSIZE) ;
  109. if (gsm_decode (pgsm610->gsm_data, pgsm610->block, pgsm610->samples) < 0)
  110. { psf_sprintf (psf, "Error from gsm_decode() on frame : %dn", pgsm610->blockcount) ;
  111. return 0 ;
  112. } ;
  113. if (gsm_decode (pgsm610->gsm_data, pgsm610->block+(GSM610_BLOCKSIZE+1)/2, pgsm610->samples+GSM610_SAMPLES/2) < 0)
  114. { psf_sprintf (psf, "Error from gsm_decode() on frame : %d.5n", pgsm610->blockcount) ;
  115. return 0 ;
  116. } ;
  117. return 1 ;
  118. } /* wav_gsm610_read_block */
  119. static
  120. int wav_gsm610_read (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610, short *ptr, int len)
  121. { int count, total = 0, index = 0 ;
  122. while (index < len)
  123. { if (pgsm610->blockcount >= pgsm610->blocks && pgsm610->samplecount >= GSM610_SAMPLES)
  124. { memset (&(ptr[index]), 0, (len - index) * sizeof (short)) ;
  125. return total ;
  126. } ;
  127. if (pgsm610->samplecount >= GSM610_SAMPLES)
  128. wav_gsm610_read_block (psf, pgsm610) ;
  129. count = GSM610_SAMPLES - pgsm610->samplecount ;
  130. count = (len - index > count) ? count : len - index ;
  131. memcpy (&(ptr[index]), &(pgsm610->samples [pgsm610->samplecount]), count * sizeof (short)) ;
  132. index += count ;
  133. pgsm610->samplecount += count ;
  134. total = index ;
  135. } ;
  136. return total ;
  137. } /* wav_gsm610_read */
  138. int wav_gsm610_read_s (SF_PRIVATE *psf, short *ptr, int len)
  139. { GSM610_PRIVATE  *pgsm610 ; 
  140. int total ;
  141. if (! psf->fdata)
  142. return 0 ;
  143. pgsm610 = (GSM610_PRIVATE*) psf->fdata ;
  144. total = wav_gsm610_read (psf, pgsm610, ptr, len) ;
  145. return total ;
  146. } /* wav_gsm610_read_s */
  147. int wav_gsm610_read_i  (SF_PRIVATE *psf, int *ptr, int len)
  148. { GSM610_PRIVATE *pgsm610 ; 
  149. short *sptr ;
  150. int k, bufferlen, readcount = 0, count ;
  151. int index = 0, total = 0 ;
  152. if (! psf->fdata)
  153. return 0 ;
  154. pgsm610 = (GSM610_PRIVATE*) psf->fdata ;
  155. sptr = (short*) psf->buffer ;
  156. bufferlen = ((SF_BUFFER_LEN / psf->blockwidth) * psf->blockwidth) / sizeof (short) ;
  157. while (len > 0)
  158. { readcount = (len >= bufferlen) ? bufferlen : len ;
  159. count = wav_gsm610_read (psf, pgsm610, sptr, readcount) ;
  160. for (k = 0 ; k < readcount ; k++)
  161. ptr [index+k] = (int) (sptr [k]) ;
  162. index += readcount ;
  163. total += count ;
  164. len -= readcount ;
  165. } ;
  166. return total ;
  167. } /* wav_gsm610_read_i */
  168. int wav_gsm610_read_d  (SF_PRIVATE *psf, double *ptr, int len, int normalize)
  169. { GSM610_PRIVATE *pgsm610 ; 
  170. short *sptr ;
  171. int k, bufferlen, readcount = 0, count ;
  172. int index = 0, total = 0 ;
  173. double normfact ;
  174. normfact = (normalize ? 1.0 / ((double) 0x8000) : 1.0) ;
  175. if (! psf->fdata)
  176. return 0 ;
  177. pgsm610 = (GSM610_PRIVATE*) psf->fdata ;
  178. sptr = (short*) psf->buffer ;
  179. bufferlen = ((SF_BUFFER_LEN / psf->blockwidth) * psf->blockwidth) / sizeof (short) ;
  180. while (len > 0)
  181. { readcount = (len >= bufferlen) ? bufferlen : len ;
  182. count = wav_gsm610_read (psf, pgsm610, sptr, readcount) ;
  183. for (k = 0 ; k < readcount ; k++)
  184. ptr [index+k] = normfact * (double) (sptr [k]) ;
  185. index += readcount ;
  186. total += count ;
  187. len -= readcount ;
  188. } ;
  189. return total ;
  190. } /* wav_gsm610_read_d */
  191. off_t    wav_gsm610_seek   (SF_PRIVATE *psf, off_t offset, int whence)
  192. { GSM610_PRIVATE *pgsm610 ; 
  193. int newblock, newsample ;
  194. if (! psf->fdata)
  195. return 0 ;
  196. pgsm610 = (GSM610_PRIVATE*) psf->fdata ;
  197. if (! (psf->blockwidth && psf->datalength && psf->dataoffset))
  198. { psf->error = SFE_BAD_SEEK ;
  199. return ((off_t) -1) ;
  200. } ;
  201. switch (whence)
  202. { case SEEK_SET :
  203. if (offset < 0 || offset > pgsm610->blocks * GSM610_SAMPLES)
  204. { psf->error = SFE_BAD_SEEK ;
  205. return ((off_t) -1) ;
  206. } ;
  207. newblock  = offset / GSM610_SAMPLES ;
  208. newsample = offset % GSM610_SAMPLES ;
  209. break ;
  210. case SEEK_CUR :
  211. if (psf->current + offset < 0 || psf->current + offset > pgsm610->blocks * GSM610_SAMPLES)
  212. { psf->error = SFE_BAD_SEEK ;
  213. return ((off_t) -1) ;
  214. } ;
  215. newblock  = (psf->current + offset) / GSM610_SAMPLES ;
  216. newsample = (psf->current + offset) % GSM610_SAMPLES ;
  217. break ;
  218. case SEEK_END :
  219. if (offset > 0 || GSM610_SAMPLES * pgsm610->blocks + offset < 0)
  220. { psf->error = SFE_BAD_SEEK ;
  221. return ((off_t) -1) ;
  222. } ;
  223. newblock  = (GSM610_SAMPLES * pgsm610->blocks + offset) / GSM610_SAMPLES ;
  224. newsample = (GSM610_SAMPLES * pgsm610->blocks + offset) % GSM610_SAMPLES ;
  225. break ;
  226. default : 
  227. psf->error = SFE_BAD_SEEK ;
  228. return ((off_t) -1) ;
  229. } ;
  230. if (psf->mode == SF_MODE_READ)
  231. { fseek (psf->file, (int) (psf->dataoffset + newblock * GSM610_BLOCKSIZE), SEEK_SET) ;
  232. pgsm610->blockcount  = newblock ;
  233. wav_gsm610_read_block (psf, pgsm610) ;
  234. pgsm610->samplecount = newsample ;
  235. }
  236. else
  237. { /* What to do about write??? */ 
  238. psf->error = SFE_BAD_SEEK ;
  239. return ((off_t) -1) ;
  240. } ;
  241. psf->current = newblock * GSM610_SAMPLES + newsample ;
  242. return psf->current ;
  243. } /* wav_gsm610_seek */
  244. /*==========================================================================================
  245. ** GSM 6.10 Write Functions.
  246. */
  247. /*==========================================================================================
  248. */
  249. static
  250. int wav_gsm610_write_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610)
  251. { int k ;
  252. /* Encode the samples. */
  253. gsm_encode (pgsm610->gsm_data, pgsm610->samples, pgsm610->block) ;
  254. gsm_encode (pgsm610->gsm_data, pgsm610->samples+GSM610_SAMPLES/2, pgsm610->block+GSM610_BLOCKSIZE/2) ;
  255. /* Write the block to disk. */
  256. if ((k = fwrite (pgsm610->block, 1, GSM610_BLOCKSIZE, psf->file)) != GSM610_BLOCKSIZE)
  257. psf_sprintf (psf, "*** Warning : short write (%d != %d).n", k, GSM610_BLOCKSIZE) ;
  258. pgsm610->samplecount = 0 ;
  259. pgsm610->blockcount ++ ;
  260. /* Set samples to zero for next block. */
  261. memset (pgsm610->samples, 0, GSM610_SAMPLES * sizeof (short)) ;
  262. return 1 ;
  263. } /* wav_gsm610_write_block */
  264. static
  265. int wav_gsm610_write (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610, short *ptr, int len)
  266. { int count, total = 0, index = 0 ;
  267. while (index < len)
  268. { count = GSM610_SAMPLES - pgsm610->samplecount ;
  269. if (count > len - index)
  270. count = len - index ;
  271. memcpy (&(pgsm610->samples [pgsm610->samplecount]), &(ptr [index]), count * sizeof (short)) ;
  272. index += count ;
  273. pgsm610->samplecount += count ;
  274. total = index ;
  275. if (pgsm610->samplecount >= GSM610_SAMPLES)
  276. wav_gsm610_write_block (psf, pgsm610) ;
  277. } ;
  278. return total ;
  279. } /* wav_gsm610_write */
  280. int wav_gsm610_write_s (SF_PRIVATE *psf, short *ptr, int len)
  281. { GSM610_PRIVATE  *pgsm610 ; 
  282. int total ;
  283. if (! psf->fdata)
  284. return 0 ;
  285. pgsm610 = (GSM610_PRIVATE*) psf->fdata ;
  286. total = wav_gsm610_write (psf, pgsm610, ptr, len) ;
  287. return total ;
  288. } /* wav_gsm610_write_s */
  289. int wav_gsm610_write_i  (SF_PRIVATE *psf, int *ptr, int len)
  290. { GSM610_PRIVATE *pgsm610 ; 
  291. short *sptr ;
  292. int k, bufferlen, writecount = 0, count ;
  293. int index = 0, total = 0 ;
  294. if (! psf->fdata)
  295. return 0 ;
  296. pgsm610 = (GSM610_PRIVATE*) psf->fdata ;
  297. sptr = (short*) psf->buffer ;
  298. bufferlen = ((SF_BUFFER_LEN / psf->blockwidth) * psf->blockwidth) / sizeof (short) ;
  299. while (len > 0)
  300. { writecount = (len >= bufferlen) ? bufferlen : len ;
  301. for (k = 0 ; k < writecount ; k++)
  302. sptr [k] = (short) ptr [index+k] ;
  303. count = wav_gsm610_write (psf, pgsm610, sptr, writecount) ;
  304. index += writecount ;
  305. total += count ;
  306. len -= writecount ;
  307. } ;
  308. return total ;
  309. } /* wav_gsm610_write_i */
  310. int wav_gsm610_write_d  (SF_PRIVATE *psf, double *ptr, int len, int normalize)
  311. { GSM610_PRIVATE *pgsm610 ; 
  312. short *sptr ;
  313. int k, bufferlen, writecount = 0, count ;
  314. int index = 0, total = 0 ;
  315. double normfact ;
  316. normfact = (normalize ? (double) 0x8000 : 1.0) ;
  317. if (! psf->fdata)
  318. return 0 ;
  319. pgsm610 = (GSM610_PRIVATE*) psf->fdata ;
  320. sptr = (short*) psf->buffer ;
  321. bufferlen = ((SF_BUFFER_LEN / psf->blockwidth) * psf->blockwidth) / sizeof (short) ;
  322. while (len > 0)
  323. { writecount = (len >= bufferlen) ? bufferlen : len ;
  324. for (k = 0 ; k < writecount ; k++)
  325. sptr [k] = (short) (normfact * ptr [index+k])  ;
  326. count = wav_gsm610_write (psf, pgsm610, sptr, writecount) ;
  327. index += writecount ;
  328. total += count ;
  329. len -= writecount ;
  330. } ;
  331. return total ;
  332. } /* wav_gsm610_write_d */
  333. int wav_gsm610_close (SF_PRIVATE  *psf)
  334. { GSM610_PRIVATE *pgsm610 ; 
  335. unsigned int dword ;
  336. if (! psf->fdata)
  337. return wav_close (psf) ;
  338. pgsm610 = (GSM610_PRIVATE*) psf->fdata ;
  339. if (psf->mode == SF_MODE_WRITE)
  340. { /* If a block has been partially assembled, write it out
  341. ** as the final block.
  342. */
  343. if (pgsm610->samplecount && pgsm610->samplecount < GSM610_SAMPLES)
  344. wav_gsm610_write_block (psf, pgsm610) ;
  345. /*  Now we know for certain the length of the file we can
  346. **  re-write correct values for the RIFF and data chunks.
  347. */
  348.  
  349. fseek (psf->file, 0, SEEK_END) ;
  350. psf->filelength = ftell (psf->file) ;
  351. /* Fix RIFF size. */
  352. dword = H2LE_INT (psf->filelength - 2 * sizeof (dword)) ;
  353. fseek (psf->file, sizeof (dword), SEEK_SET) ;
  354. fwrite (&dword, sizeof (dword), 1, psf->file) ;
  355. psf->datalength = psf->filelength - psf->dataoffset ;
  356. fseek (psf->file, (int) (psf->dataoffset - sizeof (dword)), SEEK_SET) ;
  357. dword = H2LE_INT (psf->datalength) ;
  358. fwrite (&dword, sizeof (dword), 1, psf->file) ;
  359. } ;
  360. if (pgsm610->gsm_data)
  361. gsm_destroy (pgsm610->gsm_data) ;
  362. if (psf->fdata)
  363. free (psf->fdata) ;
  364. psf->fdata = NULL ;
  365. return 0 ;
  366. } /* wav_gsm610_close */