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

流媒体/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 <ctype.h>
  22. #include <stdarg.h>
  23. #include "sndfile.h"
  24. #include "config.h"
  25. #include "sfendian.h"
  26. #include "common.h"
  27. #include "pcm.h"
  28. /*------------------------------------------------------------------------------
  29.  * Macros to handle big/little endian issues.
  30. */
  31. #if (CPU_IS_LITTLE_ENDIAN == 1)
  32. # define MAKE_MARKER(a,b,c,d) ((a)|((b)<<8)|((c)<<16)|((d)<<24))
  33. #elif (CPU_IS_BIG_ENDIAN == 1)
  34. # define MAKE_MARKER(a,b,c,d) (((a)<<24)|((b)<<16)|((c)<<8)|(d))
  35. #else
  36. # error "Cannot determine endian-ness of processor."
  37. #endif
  38. #define FORM_MARKER (MAKE_MARKER ('F', 'O', 'R', 'M'))
  39. #define SVX8_MARKER (MAKE_MARKER ('8', 'S', 'V', 'X'))
  40. #define SV16_MARKER (MAKE_MARKER ('1', '6', 'S', 'V'))
  41. #define VHDR_MARKER (MAKE_MARKER ('V', 'H', 'D', 'R'))
  42. #define BODY_MARKER (MAKE_MARKER ('B', 'O', 'D', 'Y')) 
  43.  
  44. #define ATAK_MARKER (MAKE_MARKER ('A','T','A','K'))
  45. #define RLSE_MARKER (MAKE_MARKER ('R','L','S','E'))
  46. #define c_MARKER (MAKE_MARKER ('(', 'c', ')', ' ')) 
  47. #define NAME_MARKER (MAKE_MARKER ('N', 'A', 'M', 'E')) 
  48. #define AUTH_MARKER (MAKE_MARKER ('A', 'U', 'T', 'H')) 
  49. #define ANNO_MARKER (MAKE_MARKER ('A', 'N', 'N', 'O')) 
  50. #define CHAN_MARKER (MAKE_MARKER ('C', 'H', 'A', 'N')) 
  51. /*------------------------------------------------------------------------------
  52.  * Typedefs for file chunks.
  53. */
  54. typedef struct
  55. { unsigned int oneShotHiSamples, repeatHiSamples, samplesPerHiCycle ;
  56. unsigned short samplesPerSec ;
  57. unsigned char octave, compression ;
  58. unsigned int volume ;
  59. } VHDR_CHUNK ;
  60. /*------------------------------------------------------------------------------
  61.  * Private static functions.
  62. */
  63. static int svx_close (SF_PRIVATE  *psf) ;
  64. static
  65. void endswap_vhdr_chunk (VHDR_CHUNK *vhdr)
  66. { vhdr->oneShotHiSamples  = ENDSWAP_INT (vhdr->oneShotHiSamples) ;
  67. vhdr->repeatHiSamples   = ENDSWAP_INT (vhdr->repeatHiSamples) ;
  68. vhdr->samplesPerHiCycle = ENDSWAP_INT (vhdr->samplesPerHiCycle) ;
  69. vhdr->samplesPerSec     = ENDSWAP_SHORT (vhdr->samplesPerSec) ;
  70. vhdr->volume            = ENDSWAP_INT (vhdr->volume) ;
  71. } /* endswap_vhdr_chunk */
  72. /*------------------------------------------------------------------------------
  73. ** Public functions.
  74. */
  75. int  svx_open_read (SF_PRIVATE *psf)
  76. { VHDR_CHUNK vhdr ;
  77. unsigned int FORMsize, vhdrsize, dword, marker ;
  78. int filetype = 0, parsestage = 0, done = 0 ;
  79. /* Set default number of channels. */
  80. psf->sf.channels = 1 ;
  81. while (! done)
  82. { fread (&marker, sizeof (marker), 1, psf->file) ;
  83. switch (marker)
  84. { case FORM_MARKER :
  85. if (parsestage != 0)
  86. return SFE_SVX_NO_FORM ;
  87. fread (&dword, sizeof (dword), 1, psf->file) ;
  88. FORMsize = BE2H_INT (dword) ;
  89. if (FORMsize != psf->filelength - 2 * sizeof (dword))
  90. { dword = psf->filelength - 2 * sizeof (dword);
  91. psf_sprintf (psf, "FORM : %d (should be %d)n", FORMsize, dword) ;
  92. FORMsize = dword ;
  93. }
  94. else
  95. psf_sprintf (psf, "FORM : %dn", FORMsize) ;
  96. parsestage = 1 ;
  97. break ;
  98. case SVX8_MARKER :
  99. case SV16_MARKER :
  100. if (parsestage != 1)
  101. return SFE_SVX_NO_FORM ;
  102. filetype = marker ;
  103. psf_sprintf (psf, " %Dn", marker) ;
  104. parsestage = 2 ;
  105. break ;
  106. case VHDR_MARKER :
  107. if (parsestage != 2)
  108. return SFE_SVX_NO_FORM ;
  109. fread (&dword, sizeof (dword), 1, psf->file) ;
  110. vhdrsize = BE2H_INT (dword) ;
  111. psf_sprintf (psf, " VHDR : %dn", vhdrsize) ;
  112. fread (&vhdr, sizeof (vhdr), 1, psf->file) ;
  113. if (CPU_IS_LITTLE_ENDIAN)
  114. endswap_vhdr_chunk (&vhdr) ;
  115. psf_sprintf (psf, "  OneShotHiSamples  : %dn", vhdr.oneShotHiSamples) ;
  116. psf_sprintf (psf, "  RepeatHiSamples   : %dn", vhdr.repeatHiSamples) ;
  117. psf_sprintf (psf, "  samplesPerHiCycle : %dn", vhdr.samplesPerHiCycle) ;
  118. psf_sprintf (psf, "  Sample Rate       : %dn", vhdr.samplesPerSec) ;
  119. psf_sprintf (psf, "  Octave            : %dn", vhdr.octave) ;
  120. psf_sprintf (psf, "  Compression       : %d => ", vhdr.compression) ;
  121. switch (vhdr.compression)
  122. { case 0 : psf_sprintf (psf, "None.n") ;
  123. break ;
  124. case 1 : psf_sprintf (psf, "Fibonacci deltan") ;
  125. break ;
  126. case 2 : psf_sprintf (psf, "Exponential deltan") ;
  127. break ;
  128. } ;
  129. psf_sprintf (psf, "  Volume            : %dn", vhdr.volume) ;
  130. psf->sf.samplerate  = vhdr.samplesPerSec ;
  131. if (filetype == SVX8_MARKER)
  132. psf->sf.pcmbitwidth = 8 ;
  133. else if (filetype == SV16_MARKER)
  134. psf->sf.pcmbitwidth = 16 ;
  135. parsestage = 3 ;
  136. break ;
  137. case BODY_MARKER :
  138. if (parsestage != 3)
  139. return SFE_SVX_NO_BODY ;
  140. fread (&dword, sizeof (dword), 1, psf->file) ;
  141. psf->datalength = BE2H_INT (dword) ;
  142. psf->dataoffset = ftell (psf->file) ;
  143. if (psf->datalength > psf->filelength - psf->dataoffset)
  144. { psf_sprintf (psf, " BODY : %d (should be %d)n", psf->datalength, psf->filelength - psf->dataoffset) ;
  145. psf->datalength = psf->filelength - psf->dataoffset ;
  146. else
  147. psf_sprintf (psf, " BODY : %dn", psf->datalength) ;
  148. fseek (psf->file, psf->datalength, SEEK_CUR) ;
  149. parsestage = 4 ;
  150. break ;
  151. case NAME_MARKER :
  152. case ANNO_MARKER :
  153. if (parsestage < 2)
  154. return SFE_SVX_NO_FORM ;
  155. fread (&dword, sizeof (dword), 1, psf->file) ;
  156. dword = BE2H_INT (dword) ;
  157. psf_sprintf (psf, " %D : %dn", marker, dword) ;
  158. fseek (psf->file, (int) dword, SEEK_CUR) ;
  159. break ;
  160. case AUTH_MARKER :
  161. case c_MARKER :
  162. case CHAN_MARKER :
  163. if (parsestage < 2)
  164. return SFE_SVX_NO_FORM ;
  165. fread (&dword, sizeof (dword), 1, psf->file) ;
  166. dword = BE2H_INT (dword) ;
  167. psf_sprintf (psf, " %D : %dn", marker, dword) ;
  168. fseek (psf->file, (int) dword, SEEK_CUR) ;
  169. break ;
  170. default : 
  171. if (isprint ((marker >> 24) & 0xFF) && isprint ((marker >> 16) & 0xFF)
  172. && isprint ((marker >> 8) & 0xFF) && isprint (marker & 0xFF))
  173. { fread (&dword, sizeof (dword), 1, psf->file) ;
  174. psf_sprintf (psf, "%D : %d (unknown marker)n", marker, dword) ;
  175. fseek (psf->file, (int) dword, SEEK_CUR) ;
  176. break ;
  177. } ;
  178. if ((dword = ftell (psf->file)) & 0x03)
  179. { psf_sprintf (psf, "  Unknown chunk marker at position %d. Resynching.n", dword - 4) ;
  180. fseek (psf->file, -3, SEEK_CUR) ;
  181. break ;
  182. } ;
  183. psf_sprintf (psf, "*** Unknown chunk marker : %X. Exiting parser.n", marker) ;
  184. done = 1 ;
  185. } ; /* switch (marker) */
  186. if (ferror (psf->file))
  187. { psf_sprintf (psf, "*** Error on file handle. ***n", marker) ;
  188. clearerr (psf->file) ;
  189. break ;
  190. } ;
  191. if (ftell (psf->file) >= (off_t) (psf->filelength - (2 * sizeof (dword))))
  192. break ;
  193. } ; /* while (1) */
  194. if (vhdr.compression)
  195. return SFE_SVX_BAD_COMP ;
  196. if (! psf->dataoffset)
  197. return SFE_SVX_NO_DATA ;
  198. psf->sf.format  = (SF_FORMAT_SVX | SF_FORMAT_PCM);
  199. psf->sf.sections  = 1 ;
  200. psf->current     = 0 ;
  201. psf->endian      = SF_ENDIAN_BIG ; /* All SVX files are big endian. */
  202. psf->sf.seekable = SF_TRUE ;
  203. psf->bytewidth   = BITWIDTH2BYTES (psf->sf.pcmbitwidth) ;
  204. psf->blockwidth  = psf->sf.channels * psf->bytewidth ;
  205. if (psf->blockwidth)
  206. psf->sf.samples  = psf->datalength / psf->blockwidth ;
  207. fseek (psf->file, psf->dataoffset, SEEK_SET) ;
  208. psf->close = (func_close) svx_close ;
  209. switch (psf->bytewidth)
  210. { case  1 :
  211. psf->read_short  = (func_short)  pcm_read_sc2s ;
  212. psf->read_int    = (func_int)    pcm_read_sc2i ;
  213. psf->read_double = (func_double) pcm_read_sc2d ;
  214. break ;
  215. case  2 :
  216. psf->read_short  = (func_short)  pcm_read_bes2s ;
  217. psf->read_int    = (func_int)    pcm_read_bes2i ;
  218. psf->read_double = (func_double) pcm_read_bes2d ;
  219. break ;
  220. default : 
  221. /* printf ("Weird bytewidth (%d)n", psf->bytewidth) ; */
  222. return SFE_UNIMPLEMENTED ;
  223. } ;
  224. return 0 ;
  225. } /* svx_open_read */
  226. int  svx_open_write (SF_PRIVATE *psf)
  227. { static char  annotation [] = "libsndfile by Erik de Castro Lopo" ;
  228. VHDR_CHUNK vhdr ;
  229. unsigned int FORMsize ;
  230. if ((psf->sf.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_SVX)
  231. return SFE_BAD_OPEN_FORMAT ;
  232. if ((psf->sf.format & SF_FORMAT_SUBMASK) != SF_FORMAT_PCM)
  233. return SFE_BAD_OPEN_FORMAT ;
  234. if (psf->sf.pcmbitwidth != 8 && psf->sf.pcmbitwidth != 16)
  235. return SFE_BAD_OPEN_FORMAT ;
  236. psf->endian      = SF_ENDIAN_BIG ; /* All SVX files are big endian. */
  237. psf->sf.seekable = SF_TRUE ;
  238. psf->bytewidth   = BITWIDTH2BYTES (psf->sf.pcmbitwidth) ;
  239. psf->blockwidth  = psf->bytewidth * psf->sf.channels ;
  240. psf->datalength  = psf->blockwidth * psf->sf.samples ;
  241. psf->filelength  = psf->datalength + psf->dataoffset ;
  242. psf->error       = 0 ;
  243. FORMsize   = 0x7FFFFFFF ;   /* Correct this when closing file. */
  244. vhdr.oneShotHiSamples  = psf->sf.samples ;
  245. vhdr.repeatHiSamples   = 0 ;
  246. vhdr.samplesPerHiCycle = 0 ;
  247. vhdr.samplesPerSec     = psf->sf.samplerate ;
  248. vhdr.octave            = 1 ;
  249. vhdr.compression       = 0 ;
  250. vhdr.volume            = (psf->bytewidth == 1) ? 255 : 0xFFFF ;
  251. if (CPU_IS_LITTLE_ENDIAN)
  252. endswap_vhdr_chunk (&vhdr) ;
  253. psf_hprintf (psf, "mL"  , FORM_MARKER, FORMsize) ;
  254. psf_hprintf (psf, "m"   , (psf->bytewidth == 1) ? SVX8_MARKER : SV16_MARKER) ;
  255. psf_hprintf (psf, "mLb" , VHDR_MARKER, sizeof (VHDR_CHUNK), &vhdr, sizeof (VHDR_CHUNK)) ;
  256. psf_hprintf (psf, "mSmS", NAME_MARKER, psf->filename, ANNO_MARKER, annotation) ;
  257. psf_hprintf (psf, "mL"  , BODY_MARKER, psf->datalength) ;
  258. fwrite (psf->header, psf->headindex, 1, psf->file) ;
  259. psf->dataoffset  = ftell (psf->file) ;
  260. psf->close = (func_close) svx_close ;
  261. switch (psf->bytewidth)
  262. { case  1 :
  263. psf->write_short  = (func_short) pcm_write_s2sc ;
  264. psf->write_int    = (func_int) pcm_write_i2sc ;
  265. psf->write_double = (func_double) pcm_write_d2sc ;
  266. break ;
  267. case  2 :
  268. psf->write_short  = (func_short) pcm_write_s2bes ;
  269. psf->write_int    = (func_int) pcm_write_i2bes ;
  270. psf->write_double = (func_double) pcm_write_d2bes ;
  271. break ;
  272. case  3 :
  273. psf->write_short  = (func_short) pcm_write_s2bet ;
  274. psf->write_int    = (func_int) pcm_write_i2bet ;
  275. psf->write_double = (func_double) pcm_write_d2bet ;
  276. break ;
  277. case  4 :
  278. psf->write_short  = (func_short) pcm_write_s2bei ;
  279. psf->write_int    = (func_int) pcm_write_i2bei ;
  280. psf->write_double = (func_double) pcm_write_d2bei ;
  281. break ;
  282. default : return SFE_UNIMPLEMENTED ;
  283. } ;
  284. return 0 ;
  285. } /* svx_open_write */
  286. /*------------------------------------------------------------------------------
  287. */
  288. int svx_close (SF_PRIVATE  *psf)
  289. {
  290. if (psf->mode == SF_MODE_WRITE)
  291. { /*  Now we know for certain the length of the file we can re-write 
  292. ** correct values for the FORM, 8SVX and BODY chunks.
  293. */
  294.                 
  295. fseek (psf->file, 0, SEEK_END) ;
  296. psf->filelength = ftell (psf->file) ;
  297. psf_hsetf (psf, FORM_MARKER, "L", psf->filelength - 8) ;
  298. psf_hsetf (psf, BODY_MARKER, "L", psf->filelength - psf->dataoffset) ;
  299. fseek (psf->file, 0, SEEK_SET) ;
  300. fwrite (psf->header, psf->headindex, 1, psf->file) ;
  301. } ;
  302. if (psf->fdata)
  303. free (psf->fdata) ;
  304. psf->fdata = NULL ;
  305. return 0 ;
  306. } /* svx_close */