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

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 "G72x/g72x.h"
  27. /* This struct is private to the G72x code. */
  28. struct g72x_state ;
  29. typedef struct g72x_state G72x_STATE ;
  30. typedef struct
  31. { /* Private data. Don't mess with it. */
  32. struct g72x_state * private ;
  33. /* Public data. Read only. */
  34. int blocksize, samplesperblock, bytesperblock ;
  35. /* Public data. Read and write. */
  36. int blocks_total, block_curr, sample_curr ;
  37. unsigned char block [G72x_BLOCK_SIZE] ;
  38. short samples [G72x_BLOCK_SIZE] ;
  39. } G72x_PRIVATE ;
  40. static int psf_g72x_decode_block (SF_PRIVATE *psf, G72x_PRIVATE *pg72x) ;
  41. static int psf_g72x_encode_block (SF_PRIVATE *psf, G72x_PRIVATE *pg72x) ;
  42. static sf_count_t g72x_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
  43. static sf_count_t g72x_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
  44. static sf_count_t g72x_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
  45. static sf_count_t g72x_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
  46. static sf_count_t g72x_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
  47. static sf_count_t g72x_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
  48. static sf_count_t g72x_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
  49. static sf_count_t g72x_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
  50. static sf_count_t g72x_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
  51. static int g72x_close (SF_PRIVATE *psf) ;
  52. /*============================================================================================
  53. ** WAV G721 Reader initialisation function.
  54. */
  55. int
  56. g72x_init (SF_PRIVATE * psf)
  57. { G72x_PRIVATE *pg72x ;
  58. int bitspersample, bytesperblock, codec ;
  59. if (psf->codec_data != NULL)
  60. { psf_log_printf (psf, "*** psf->codec_data is not NULL.n") ;
  61. return SFE_INTERNAL ;
  62. } ;
  63. psf->sf.seekable = SF_FALSE ;
  64. if (psf->sf.channels != 1)
  65. return SFE_G72X_NOT_MONO ;
  66. if ((pg72x = calloc (1, sizeof (G72x_PRIVATE))) == NULL)
  67. return SFE_MALLOC_FAILED ;
  68. psf->codec_data = (void*) pg72x ;
  69. pg72x->block_curr = 0 ;
  70. pg72x->sample_curr = 0 ;
  71. switch (SF_CODEC (psf->sf.format))
  72. { case SF_FORMAT_G721_32 :
  73. codec = G721_32_BITS_PER_SAMPLE ;
  74. bytesperblock = G721_32_BYTES_PER_BLOCK ;
  75. bitspersample = G721_32_BITS_PER_SAMPLE ;
  76. break ;
  77. case SF_FORMAT_G723_24:
  78. codec = G723_24_BITS_PER_SAMPLE ;
  79. bytesperblock = G723_24_BYTES_PER_BLOCK ;
  80. bitspersample = G723_24_BITS_PER_SAMPLE ;
  81. break ;
  82. case SF_FORMAT_G723_40:
  83. codec = G723_40_BITS_PER_SAMPLE ;
  84. bytesperblock = G723_40_BYTES_PER_BLOCK ;
  85. bitspersample = G723_40_BITS_PER_SAMPLE ;
  86. break ;
  87. default : return SFE_UNIMPLEMENTED ;
  88. } ;
  89. psf->blockwidth = psf->bytewidth = 1 ;
  90. psf->filelength = psf_get_filelen (psf) ;
  91. if (psf->filelength < psf->dataoffset)
  92. psf->filelength = psf->dataoffset ;
  93. psf->datalength = psf->filelength - psf->dataoffset ;
  94. if (psf->dataend > 0)
  95. psf->datalength -= psf->filelength - psf->dataend ;
  96. if (psf->file.mode == SFM_READ)
  97. { pg72x->private = g72x_reader_init (codec, &(pg72x->blocksize), &(pg72x->samplesperblock)) ;
  98. if (pg72x->private == NULL)
  99. return SFE_MALLOC_FAILED ;
  100. pg72x->bytesperblock = bytesperblock ;
  101. psf->read_short = g72x_read_s ;
  102. psf->read_int = g72x_read_i ;
  103. psf->read_float = g72x_read_f ;
  104. psf->read_double = g72x_read_d ;
  105.   psf->seek = g72x_seek ;
  106. if (psf->datalength % pg72x->blocksize)
  107. { psf_log_printf (psf, "*** Odd psf->datalength (%D) should be a multiple of %dn", psf->datalength, pg72x->blocksize) ;
  108. pg72x->blocks_total = (psf->datalength / pg72x->blocksize) + 1 ;
  109. }
  110. else
  111. pg72x->blocks_total = psf->datalength / pg72x->blocksize ;
  112. psf->sf.frames = pg72x->blocks_total * pg72x->samplesperblock ;
  113. psf_g72x_decode_block (psf, pg72x) ;
  114. }
  115. else if (psf->file.mode == SFM_WRITE)
  116. { pg72x->private = g72x_writer_init (codec, &(pg72x->blocksize), &(pg72x->samplesperblock)) ;
  117. if (pg72x->private == NULL)
  118. return SFE_MALLOC_FAILED ;
  119. pg72x->bytesperblock = bytesperblock ;
  120. psf->write_short = g72x_write_s ;
  121. psf->write_int = g72x_write_i ;
  122. psf->write_float = g72x_write_f ;
  123. psf->write_double = g72x_write_d ;
  124. if (psf->datalength % pg72x->blocksize)
  125. pg72x->blocks_total = (psf->datalength / pg72x->blocksize) + 1 ;
  126. else
  127. pg72x->blocks_total = psf->datalength / pg72x->blocksize ;
  128. if (psf->datalength > 0)
  129. psf->sf.frames = (8 * psf->datalength) / bitspersample ;
  130. if ((psf->sf.frames * bitspersample) / 8 != psf->datalength)
  131. psf_log_printf (psf, "*** Warning : weird psf->datalength.n") ;
  132. } ;
  133. psf->codec_close = g72x_close ;
  134. return 0 ;
  135. } /* g72x_init */
  136. /*============================================================================================
  137. ** G721 Read Functions.
  138. */
  139. static int
  140. psf_g72x_decode_block (SF_PRIVATE *psf, G72x_PRIVATE *pg72x)
  141. { int k ;
  142. pg72x->block_curr ++ ;
  143. pg72x->sample_curr = 0 ;
  144. if (pg72x->block_curr > pg72x->blocks_total)
  145. { memset (pg72x->samples, 0, G72x_BLOCK_SIZE * sizeof (short)) ;
  146. return 1 ;
  147. } ;
  148. if ((k = psf_fread (pg72x->block, 1, pg72x->bytesperblock, psf)) != pg72x->bytesperblock)
  149. psf_log_printf (psf, "*** Warning : short read (%d != %d).n", k, pg72x->bytesperblock) ;
  150. pg72x->blocksize = k ;
  151. g72x_decode_block (pg72x->private, pg72x->block, pg72x->samples) ;
  152. return 1 ;
  153. } /* psf_g72x_decode_block */
  154. static int
  155. g72x_read_block (SF_PRIVATE *psf, G72x_PRIVATE *pg72x, short *ptr, int len)
  156. { int count, total = 0, indx = 0 ;
  157. while (indx < len)
  158. { if (pg72x->block_curr > pg72x->blocks_total)
  159. { memset (&(ptr [indx]), 0, (len - indx) * sizeof (short)) ;
  160. return total ;
  161. } ;
  162. if (pg72x->sample_curr >= pg72x->samplesperblock)
  163. psf_g72x_decode_block (psf, pg72x) ;
  164. count = pg72x->samplesperblock - pg72x->sample_curr ;
  165. count = (len - indx > count) ? count : len - indx ;
  166. memcpy (&(ptr [indx]), &(pg72x->samples [pg72x->sample_curr]), count * sizeof (short)) ;
  167. indx += count ;
  168. pg72x->sample_curr += count ;
  169. total = indx ;
  170. } ;
  171. return total ;
  172. } /* g72x_read_block */
  173. static sf_count_t
  174. g72x_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
  175. { G72x_PRIVATE  *pg72x ;
  176. int readcount, count ;
  177. sf_count_t total = 0 ;
  178. if (psf->codec_data == NULL)
  179. return 0 ;
  180. pg72x = (G72x_PRIVATE*) psf->codec_data ;
  181. while (len > 0)
  182. { readcount = (len > 0x10000000) ? 0x10000000 : (int) len ;
  183. count = g72x_read_block (psf, pg72x, ptr, readcount) ;
  184. total += count ;
  185. len -= count ;
  186. if (count != readcount)
  187. break ;
  188. } ;
  189. return total ;
  190. } /* g72x_read_s */
  191. static sf_count_t
  192. g72x_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
  193. { G72x_PRIVATE *pg72x ;
  194. short *sptr ;
  195. int k, bufferlen, readcount = 0, count ;
  196. sf_count_t total = 0 ;
  197. if (psf->codec_data == NULL)
  198. return 0 ;
  199. pg72x = (G72x_PRIVATE*) psf->codec_data ;
  200. sptr = psf->u.sbuf ;
  201. bufferlen = SF_BUFFER_LEN / sizeof (short) ;
  202. while (len > 0)
  203. { readcount = (len >= bufferlen) ? bufferlen : len ;
  204. count = g72x_read_block (psf, pg72x, sptr, readcount) ;
  205. for (k = 0 ; k < readcount ; k++)
  206. ptr [total + k] = sptr [k] << 16 ;
  207. total += count ;
  208. len -= readcount ;
  209. if (count != readcount)
  210. break ;
  211. } ;
  212. return total ;
  213. } /* g72x_read_i */
  214. static sf_count_t
  215. g72x_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
  216. { G72x_PRIVATE *pg72x ;
  217. short *sptr ;
  218. int k, bufferlen, readcount = 0, count ;
  219. sf_count_t total = 0 ;
  220. float  normfact ;
  221. if (psf->codec_data == NULL)
  222. return 0 ;
  223. pg72x = (G72x_PRIVATE*) psf->codec_data ;
  224. normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x8000) : 1.0 ;
  225. sptr = psf->u.sbuf ;
  226. bufferlen = SF_BUFFER_LEN / sizeof (short) ;
  227. while (len > 0)
  228. { readcount = (len >= bufferlen) ? bufferlen : len ;
  229. count = g72x_read_block (psf, pg72x, sptr, readcount) ;
  230. for (k = 0 ; k < readcount ; k++)
  231. ptr [total + k] = normfact * sptr [k] ;
  232. total += count ;
  233. len -= readcount ;
  234. if (count != readcount)
  235. break ;
  236. } ;
  237. return total ;
  238. } /* g72x_read_f */
  239. static sf_count_t
  240. g72x_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
  241. { G72x_PRIVATE *pg72x ;
  242. short *sptr ;
  243. int k, bufferlen, readcount = 0, count ;
  244. sf_count_t total = 0 ;
  245. double normfact ;
  246. if (psf->codec_data == NULL)
  247. return 0 ;
  248. pg72x = (G72x_PRIVATE*) psf->codec_data ;
  249. normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x8000) : 1.0 ;
  250. sptr = psf->u.sbuf ;
  251. bufferlen = SF_BUFFER_LEN / sizeof (short) ;
  252. while (len > 0)
  253. { readcount = (len >= bufferlen) ? bufferlen : len ;
  254. count = g72x_read_block (psf, pg72x, sptr, readcount) ;
  255. for (k = 0 ; k < readcount ; k++)
  256. ptr [total + k] = normfact * (double) (sptr [k]) ;
  257. total += count ;
  258. len -= readcount ;
  259. if (count != readcount)
  260. break ;
  261. } ;
  262. return total ;
  263. } /* g72x_read_d */
  264. static sf_count_t
  265. g72x_seek (SF_PRIVATE *psf, int UNUSED (mode), sf_count_t UNUSED (offset))
  266. {
  267. psf_log_printf (psf, "seek unsupportedn") ;
  268. /* No simple solution. To do properly, would need to seek
  269. ** to start of file and decode everything up to seek position.
  270. ** Maybe implement SEEK_SET to 0 only?
  271. */
  272. return 0 ;
  273. /*
  274. ** G72x_PRIVATE *pg72x ;
  275. ** int newblock, newsample, sample_curr ;
  276. **
  277. ** if (psf->codec_data == NULL)
  278. ** return 0 ;
  279. ** pg72x = (G72x_PRIVATE*) psf->codec_data ;
  280. **
  281. ** if (! (psf->datalength && psf->dataoffset))
  282. ** { psf->error = SFE_BAD_SEEK ;
  283. ** return PSF_SEEK_ERROR ;
  284. ** } ;
  285. **
  286. ** sample_curr = (8 * psf->datalength) / G721_32_BITS_PER_SAMPLE ;
  287. **
  288. ** switch (whence)
  289. ** { case SEEK_SET :
  290. ** if (offset < 0 || offset > sample_curr)
  291. ** { psf->error = SFE_BAD_SEEK ;
  292. ** return PSF_SEEK_ERROR ;
  293. ** } ;
  294. ** newblock  = offset / pg72x->samplesperblock ;
  295. ** newsample = offset % pg72x->samplesperblock ;
  296. ** break ;
  297. **
  298. ** case SEEK_CUR :
  299. ** if (psf->current + offset < 0 || psf->current + offset > sample_curr)
  300. ** { psf->error = SFE_BAD_SEEK ;
  301. ** return PSF_SEEK_ERROR ;
  302. ** } ;
  303. ** newblock  = (8 * (psf->current + offset)) / pg72x->samplesperblock ;
  304. ** newsample = (8 * (psf->current + offset)) % pg72x->samplesperblock ;
  305. ** break ;
  306. **
  307. ** case SEEK_END :
  308. ** if (offset > 0 || sample_curr + offset < 0)
  309. ** { psf->error = SFE_BAD_SEEK ;
  310. ** return PSF_SEEK_ERROR ;
  311. ** } ;
  312. ** newblock  = (sample_curr + offset) / pg72x->samplesperblock ;
  313. ** newsample = (sample_curr + offset) % pg72x->samplesperblock ;
  314. ** break ;
  315. **
  316. ** default :
  317. ** psf->error = SFE_BAD_SEEK ;
  318. ** return PSF_SEEK_ERROR ;
  319. ** } ;
  320. **
  321. ** if (psf->file.mode == SFM_READ)
  322. ** { psf_fseek (psf, psf->dataoffset + newblock * pg72x->blocksize, SEEK_SET) ;
  323. ** pg72x->block_curr  = newblock ;
  324. ** psf_g72x_decode_block (psf, pg72x) ;
  325. ** pg72x->sample_curr = newsample ;
  326. ** }
  327. ** else
  328. ** { /+* What to do about write??? *+/
  329. ** psf->error = SFE_BAD_SEEK ;
  330. ** return PSF_SEEK_ERROR ;
  331. ** } ;
  332. **
  333. ** psf->current = newblock * pg72x->samplesperblock + newsample ;
  334. ** return psf->current ;
  335. **
  336. */
  337. } /* g72x_seek */
  338. /*==========================================================================================
  339. ** G72x Write Functions.
  340. */
  341. static int
  342. psf_g72x_encode_block (SF_PRIVATE *psf, G72x_PRIVATE *pg72x)
  343. { int k ;
  344. /* Encode the samples. */
  345. g72x_encode_block (pg72x->private, pg72x->samples, pg72x->block) ;
  346. /* Write the block to disk. */
  347. if ((k = psf_fwrite (pg72x->block, 1, pg72x->blocksize, psf)) != pg72x->blocksize)
  348. psf_log_printf (psf, "*** Warning : short write (%d != %d).n", k, pg72x->blocksize) ;
  349. pg72x->sample_curr = 0 ;
  350. pg72x->block_curr ++ ;
  351. /* Set samples to zero for next block. */
  352. memset (pg72x->samples, 0, G72x_BLOCK_SIZE * sizeof (short)) ;
  353. return 1 ;
  354. } /* psf_g72x_encode_block */
  355. static int
  356. g72x_write_block (SF_PRIVATE *psf, G72x_PRIVATE *pg72x, const short *ptr, int len)
  357. { int count, total = 0, indx = 0 ;
  358. while (indx < len)
  359. { count = pg72x->samplesperblock - pg72x->sample_curr ;
  360. if (count > len - indx)
  361. count = len - indx ;
  362. memcpy (&(pg72x->samples [pg72x->sample_curr]), &(ptr [indx]), count * sizeof (short)) ;
  363. indx += count ;
  364. pg72x->sample_curr += count ;
  365. total = indx ;
  366. if (pg72x->sample_curr >= pg72x->samplesperblock)
  367. psf_g72x_encode_block (psf, pg72x) ;
  368. } ;
  369. return total ;
  370. } /* g72x_write_block */
  371. static sf_count_t
  372. g72x_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
  373. { G72x_PRIVATE  *pg72x ;
  374. int writecount, count ;
  375. sf_count_t total = 0 ;
  376. if (psf->codec_data == NULL)
  377. return 0 ;
  378. pg72x = (G72x_PRIVATE*) psf->codec_data ;
  379. while (len > 0)
  380. { writecount = (len > 0x10000000) ? 0x10000000 : (int) len ;
  381. count = g72x_write_block (psf, pg72x, ptr, writecount) ;
  382. total += count ;
  383. len -= count ;
  384. if (count != writecount)
  385. break ;
  386. } ;
  387. return total ;
  388. } /* g72x_write_s */
  389. static sf_count_t
  390. g72x_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
  391. { G72x_PRIVATE *pg72x ;
  392. short *sptr ;
  393. int k, bufferlen, writecount = 0, count ;
  394. sf_count_t total = 0 ;
  395. if (psf->codec_data == NULL)
  396. return 0 ;
  397. pg72x = (G72x_PRIVATE*) psf->codec_data ;
  398. sptr = psf->u.sbuf ;
  399. bufferlen = ((SF_BUFFER_LEN / psf->blockwidth) * psf->blockwidth) / sizeof (short) ;
  400. while (len > 0)
  401. { writecount = (len >= bufferlen) ? bufferlen : len ;
  402. for (k = 0 ; k < writecount ; k++)
  403. sptr [k] = ptr [total + k] >> 16 ;
  404. count = g72x_write_block (psf, pg72x, sptr, writecount) ;
  405. total += count ;
  406. len -= writecount ;
  407. if (count != writecount)
  408. break ;
  409. } ;
  410. return total ;
  411. } /* g72x_write_i */
  412. static sf_count_t
  413. g72x_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
  414. { G72x_PRIVATE *pg72x ;
  415. short *sptr ;
  416. int k, bufferlen, writecount = 0, count ;
  417. sf_count_t total = 0 ;
  418. float normfact ;
  419. if (psf->codec_data == NULL)
  420. return 0 ;
  421. pg72x = (G72x_PRIVATE*) psf->codec_data ;
  422. normfact = (psf->norm_float == SF_TRUE) ? (1.0 * 0x8000) : 1.0 ;
  423. sptr = psf->u.sbuf ;
  424. bufferlen = ((SF_BUFFER_LEN / psf->blockwidth) * psf->blockwidth) / sizeof (short) ;
  425. while (len > 0)
  426. { writecount = (len >= bufferlen) ? bufferlen : len ;
  427. for (k = 0 ; k < writecount ; k++)
  428. sptr [k] = lrintf (normfact * ptr [total + k]) ;
  429. count = g72x_write_block (psf, pg72x, sptr, writecount) ;
  430. total += count ;
  431. len -= writecount ;
  432. if (count != writecount)
  433. break ;
  434. } ;
  435. return total ;
  436. } /* g72x_write_f */
  437. static sf_count_t
  438. g72x_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
  439. { G72x_PRIVATE *pg72x ;
  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. pg72x = (G72x_PRIVATE*) psf->codec_data ;
  447. normfact = (psf->norm_double == SF_TRUE) ? (1.0 * 0x8000) : 1.0 ;
  448. sptr = psf->u.sbuf ;
  449. bufferlen = ((SF_BUFFER_LEN / psf->blockwidth) * psf->blockwidth) / sizeof (short) ;
  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 = g72x_write_block (psf, pg72x, sptr, writecount) ;
  455. total += count ;
  456. len -= writecount ;
  457. if (count != writecount)
  458. break ;
  459. } ;
  460. return total ;
  461. } /* g72x_write_d */
  462. static int
  463. g72x_close (SF_PRIVATE *psf)
  464. { G72x_PRIVATE *pg72x ;
  465. pg72x = (G72x_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 (pg72x->sample_curr && pg72x->sample_curr < G72x_BLOCK_SIZE)
  471. psf_g72x_encode_block (psf, pg72x) ;
  472. if (psf->write_header)
  473. psf->write_header (psf, SF_FALSE) ;
  474. } ;
  475. /* Only free the pointer allocated by g72x_(reader|writer)_init. */
  476. free (pg72x->private) ;
  477. return 0 ;
  478. } /* g72x_close */