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

Audio

开发平台:

Unix_Linux

  1. /*
  2. ** Copyright (C) 2001-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 <string.h>
  21. #include <ctype.h>
  22. #include <stdarg.h>
  23. #include "sndfile.h"
  24. #include "sfendian.h"
  25. #include "common.h"
  26. #if (ENABLE_EXPERIMENTAL_CODE == 0)
  27. int
  28. rx2_open (SF_PRIVATE *psf)
  29. { if (psf)
  30. return SFE_UNIMPLEMENTED ;
  31. return 0 ;
  32. } /* rx2_open */
  33. #else
  34. /*------------------------------------------------------------------------------
  35.  * Macros to handle big/little endian issues.
  36. */
  37. #define CAT_MARKER (MAKE_MARKER ('C', 'A', 'T', ' '))
  38. #define GLOB_MARKER (MAKE_MARKER ('G', 'L', 'O', 'B'))
  39. #define RECY_MARKER (MAKE_MARKER ('R', 'E', 'C', 'Y'))
  40. #define SLCL_MARKER (MAKE_MARKER ('S', 'L', 'C', 'L'))
  41. #define SLCE_MARKER (MAKE_MARKER ('S', 'L', 'C', 'E'))
  42. #define DEVL_MARKER (MAKE_MARKER ('D', 'E', 'V', 'L'))
  43. #define TRSH_MARKER (MAKE_MARKER ('T', 'R', 'S', 'H'))
  44. #define EQ_MARKER (MAKE_MARKER ('E', 'Q', ' ', ' '))
  45. #define COMP_MARKER (MAKE_MARKER ('C', 'O', 'M', 'P'))
  46. #define SINF_MARKER (MAKE_MARKER ('S', 'I', 'N', 'F'))
  47. #define SDAT_MARKER (MAKE_MARKER ('S', 'D', 'A', 'T'))
  48. /*------------------------------------------------------------------------------
  49.  * Typedefs for file chunks.
  50. */
  51. /*------------------------------------------------------------------------------
  52.  * Private static functions.
  53. */
  54. static int rx2_close (SF_PRIVATE *psf) ;
  55. /*------------------------------------------------------------------------------
  56. ** Public functions.
  57. */
  58. int
  59. rx2_open (SF_PRIVATE *psf)
  60. { static const char *marker_type [4] =
  61. { "Original Enabled", "Enabled Hidden",
  62. "Additional/PencilTool", "Disabled"
  63. } ;
  64. int error, marker, length, glob_offset, slce_count, frames ;
  65. int sdat_length = 0, slce_total = 0 ;
  66. int n_channels ;
  67. /* So far only doing read. */
  68. psf_binheader_readf (psf, "Epm4", 0, &marker, &length) ;
  69. if (marker != CAT_MARKER)
  70. { psf_log_printf (psf, "length : %dn", length) ;
  71. return -1000 ;
  72. } ;
  73. if (length != psf->filelength - 8)
  74. psf_log_printf (psf, "%M : %d (should be %d)n", marker, length, psf->filelength - 8) ;
  75. else
  76. psf_log_printf (psf, "%M : %dn", marker, length) ;
  77. /* 'REX2' marker */
  78. psf_binheader_readf (psf, "m", &marker) ;
  79. psf_log_printf (psf, "%M", marker) ;
  80. /* 'HEAD' marker */
  81. psf_binheader_readf (psf, "m", &marker) ;
  82. psf_log_printf (psf, "%Mn", marker) ;
  83. /* Grab 'GLOB' offset. */
  84. psf_binheader_readf (psf, "E4", &glob_offset) ;
  85. glob_offset += 0x14 ; /* Add the current file offset. */
  86. /* Jump to offset 0x30 */
  87. psf_binheader_readf (psf, "p", 0x30) ;
  88. /* Get name length */
  89. length = 0 ;
  90. psf_binheader_readf (psf, "1", &length) ;
  91. if (length >= SIGNED_SIZEOF (psf->u.cbuf))
  92. { psf_log_printf (psf, "  Text : %d *** Error : Too sf_count_t!n") ;
  93. return -1001 ;
  94. }
  95. memset (psf->u.cbuf, 0, sizeof (psf->u.cbuf)) ;
  96. psf_binheader_readf (psf, "b", psf->u.cbuf, length) ;
  97. psf_log_printf (psf, " Text : "%s"n", psf->u.cbuf) ;
  98. /* Jump to GLOB offset position. */
  99. if (glob_offset & 1)
  100. glob_offset ++ ;
  101. psf_binheader_readf (psf, "p", glob_offset) ;
  102. slce_count = 0 ;
  103. /* GLOB */
  104. while (1)
  105. { psf_binheader_readf (psf, "m", &marker) ;
  106. if (marker != SLCE_MARKER && slce_count > 0)
  107. { psf_log_printf (psf, "   SLCE count : %dn", slce_count) ;
  108. slce_count = 0 ;
  109. }
  110. switch (marker)
  111. { case GLOB_MARKER:
  112. psf_binheader_readf (psf, "E4", &length) ;
  113. psf_log_printf (psf, " %M : %dn", marker, length) ;
  114. psf_binheader_readf (psf, "j", length) ;
  115. break ;
  116. case RECY_MARKER:
  117. psf_binheader_readf (psf, "E4", &length) ;
  118. psf_log_printf (psf, " %M : %dn", marker, length) ;
  119. psf_binheader_readf (psf, "j", (length+1) & 0xFFFFFFFE) ; /* ?????? */
  120. break ;
  121. case CAT_MARKER:
  122. psf_binheader_readf (psf, "E4", &length) ;
  123. psf_log_printf (psf, " %M : %dn", marker, length) ;
  124. /*-psf_binheader_readf (psf, "j", length) ;-*/
  125. break ;
  126. case DEVL_MARKER:
  127. psf_binheader_readf (psf, "mE4", &marker, &length) ;
  128. psf_log_printf (psf, "  DEVL%M : %dn", marker, length) ;
  129. if (length & 1)
  130. length ++ ;
  131. psf_binheader_readf (psf, "j", length) ;
  132. break ;
  133. case EQ_MARKER:
  134. case COMP_MARKER:
  135. psf_binheader_readf (psf, "E4", &length) ;
  136. psf_log_printf (psf, "   %M : %dn", marker, length) ;
  137. /* This is weird!!!! why make this (length - 1) */
  138. if (length & 1)
  139. length ++ ;
  140. psf_binheader_readf (psf, "j", length) ;
  141. break ;
  142. case SLCL_MARKER:
  143. psf_log_printf (psf, "  %Mn    (Offset, Next Offset, Type)n", marker) ;
  144. slce_count = 0 ;
  145. break ;
  146. case SLCE_MARKER:
  147. { int len [4], indx ;
  148. psf_binheader_readf (psf, "E4444", &len [0], &len [1], &len [2], &len [3]) ;
  149. indx = ((len [3] & 0x0000FFFF) >> 8) & 3 ;
  150. if (len [2] == 1)
  151. { if (indx != 1)
  152. indx = 3 ; /* 2 cases, where next slice offset = 1 -> disabled & enabled/hidden */
  153. psf_log_printf (psf, "   %M : (%6d, ?: 0x%X, %s)n", marker, len [1], (len [3] & 0xFFFF0000) >> 16, marker_type [indx]) ;
  154. }
  155. else
  156. { slce_total += len [2] ;
  157. psf_log_printf (psf, "   %M : (%6d, SLCE_next_ofs:%d, ?: 0x%X, %s)n", marker, len [1], len [2], (len [3] & 0xFFFF0000) >> 16, marker_type [indx]) ;
  158. } ;
  159. slce_count ++ ;
  160. } ;
  161. break ;
  162. case SINF_MARKER:
  163. psf_binheader_readf (psf, "E4", &length) ;
  164. psf_log_printf (psf, " %M : %dn", marker, length) ;
  165. psf_binheader_readf (psf, "E2", &n_channels) ;
  166. n_channels = (n_channels & 0x0000FF00) >> 8 ;
  167. psf_log_printf (psf, "  Channels    : %dn", n_channels) ;
  168. psf_binheader_readf (psf, "E44", &psf->sf.samplerate, &frames) ;
  169. psf->sf.frames = frames ;
  170. psf_log_printf (psf, "  Sample Rate : %dn", psf->sf.samplerate) ;
  171. psf_log_printf (psf, "  Frames      : %Dn", psf->sf.frames) ;
  172. psf_binheader_readf (psf, "E4", &length) ;
  173. psf_log_printf (psf, "  ??????????? : %dn", length) ;
  174. psf_binheader_readf (psf, "E4", &length) ;
  175. psf_log_printf (psf, "  ??????????? : %dn", length) ;
  176. break ;
  177. case SDAT_MARKER:
  178. psf_binheader_readf (psf, "E4", &length) ;
  179. sdat_length = length ;
  180. /* Get the current offset. */
  181. psf->dataoffset = psf_binheader_readf (psf, NULL) ;
  182. if (psf->dataoffset + length != psf->filelength)
  183. psf_log_printf (psf, " %M : %d (should be %d)n", marker, length, psf->dataoffset + psf->filelength) ;
  184. else
  185. psf_log_printf (psf, " %M : %dn", marker, length) ;
  186. break ;
  187. default :
  188. psf_log_printf (psf, "Unknown marker : 0x%X %M", marker, marker) ;
  189. return -1003 ;
  190. break ;
  191. } ;
  192. /* SDAT always last marker in file. */
  193. if (marker == SDAT_MARKER)
  194. break ;
  195. } ;
  196. puts (psf->logbuffer) ;
  197. puts ("-----------------------------------") ;
  198. printf ("SDAT length  : %dn", sdat_length) ;
  199. printf ("SLCE count   : %dn", slce_count) ;
  200. /* Hack for zero slice count. */
  201. if (slce_count == 0 && slce_total == 1)
  202. slce_total = frames ;
  203. printf ("SLCE samples : %dn", slce_total) ;
  204. /* Two bytes per sample. */
  205. printf ("Comp Ratio   : %f:1n", (2.0 * slce_total * n_channels) / sdat_length) ;
  206. puts (" ") ;
  207. psf->logbuffer [0] = 0 ;
  208. /* OK, have the header although not too sure what it all means. */
  209. psf->endian = SF_ENDIAN_BIG ;
  210. psf->datalength = psf->filelength - psf->dataoffset ;
  211.   if (psf_fseek (psf, psf->dataoffset, SEEK_SET))
  212. return SFE_BAD_SEEK ;
  213. psf->sf.format = (SF_FORMAT_REX2 | SF_FORMAT_DWVW_12) ;
  214. psf->sf.channels = 1 ;
  215. psf->bytewidth = 2 ;
  216. psf->blockwidth = psf->sf.channels * psf->bytewidth ;
  217. if ((error = dwvw_init (psf, 16)))
  218. return error ;
  219. psf->container_close = rx2_close ;
  220. if (! psf->sf.frames && psf->blockwidth)
  221. psf->sf.frames = psf->datalength / psf->blockwidth ;
  222. /* All done. */
  223. return 0 ;
  224. } /* rx2_open */
  225. /*------------------------------------------------------------------------------
  226. */
  227. static int
  228. rx2_close (SF_PRIVATE *psf)
  229. {
  230. if (psf->file.mode == SFM_WRITE)
  231. { /*  Now we know for certain the length of the file we can re-write
  232. ** correct values for the FORM, 8SVX and BODY chunks.
  233. */
  234. } ;
  235. return 0 ;
  236. } /* rx2_close */
  237. #endif