rx2.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. /*
  2. ** Copyright (C) 2001-2012 Erik de Castro Lopo <[email protected]>
  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. BUF_UNION ubuf ;
  65. int error, marker, length, glob_offset, slce_count, frames ;
  66. int sdat_length = 0, slce_total = 0 ;
  67. int n_channels ;
  68. /* So far only doing read. */
  69. psf_binheader_readf (psf, "Epm4", 0, &marker, &length) ;
  70. if (marker != CAT_MARKER)
  71. { psf_log_printf (psf, "length : %d\n", length) ;
  72. return -1000 ;
  73. } ;
  74. if (length != psf->filelength - 8)
  75. psf_log_printf (psf, "%M : %d (should be %d)\n", marker, length, psf->filelength - 8) ;
  76. else
  77. psf_log_printf (psf, "%M : %d\n", marker, length) ;
  78. /* 'REX2' marker */
  79. psf_binheader_readf (psf, "m", &marker) ;
  80. psf_log_printf (psf, "%M", marker) ;
  81. /* 'HEAD' marker */
  82. psf_binheader_readf (psf, "m", &marker) ;
  83. psf_log_printf (psf, "%M\n", marker) ;
  84. /* Grab 'GLOB' offset. */
  85. psf_binheader_readf (psf, "E4", &glob_offset) ;
  86. glob_offset += 0x14 ; /* Add the current file offset. */
  87. /* Jump to offset 0x30 */
  88. psf_binheader_readf (psf, "p", 0x30) ;
  89. /* Get name length */
  90. length = 0 ;
  91. psf_binheader_readf (psf, "1", &length) ;
  92. if (length >= SIGNED_SIZEOF (ubuf.cbuf))
  93. { psf_log_printf (psf, " Text : %d *** Error : Too sf_count_t!\n") ;
  94. return -1001 ;
  95. }
  96. memset (ubuf.cbuf, 0, sizeof (ubuf.cbuf)) ;
  97. psf_binheader_readf (psf, "b", ubuf.cbuf, length) ;
  98. psf_log_printf (psf, " Text : \"%s\"\n", ubuf.cbuf) ;
  99. /* Jump to GLOB offset position. */
  100. if (glob_offset & 1)
  101. glob_offset ++ ;
  102. psf_binheader_readf (psf, "p", glob_offset) ;
  103. slce_count = 0 ;
  104. /* GLOB */
  105. while (1)
  106. { psf_binheader_readf (psf, "m", &marker) ;
  107. if (marker != SLCE_MARKER && slce_count > 0)
  108. { psf_log_printf (psf, " SLCE count : %d\n", slce_count) ;
  109. slce_count = 0 ;
  110. }
  111. switch (marker)
  112. { case GLOB_MARKER:
  113. psf_binheader_readf (psf, "E4", &length) ;
  114. psf_log_printf (psf, " %M : %d\n", marker, length) ;
  115. psf_binheader_readf (psf, "j", length) ;
  116. break ;
  117. case RECY_MARKER:
  118. psf_binheader_readf (psf, "E4", &length) ;
  119. psf_log_printf (psf, " %M : %d\n", marker, length) ;
  120. psf_binheader_readf (psf, "j", (length+1) & 0xFFFFFFFE) ; /* ?????? */
  121. break ;
  122. case CAT_MARKER:
  123. psf_binheader_readf (psf, "E4", &length) ;
  124. psf_log_printf (psf, " %M : %d\n", marker, length) ;
  125. /*-psf_binheader_readf (psf, "j", length) ;-*/
  126. break ;
  127. case DEVL_MARKER:
  128. psf_binheader_readf (psf, "mE4", &marker, &length) ;
  129. psf_log_printf (psf, " DEVL%M : %d\n", marker, length) ;
  130. if (length & 1)
  131. length ++ ;
  132. psf_binheader_readf (psf, "j", length) ;
  133. break ;
  134. case EQ_MARKER:
  135. case COMP_MARKER:
  136. psf_binheader_readf (psf, "E4", &length) ;
  137. psf_log_printf (psf, " %M : %d\n", marker, length) ;
  138. /* This is weird!!!! why make this (length - 1) */
  139. if (length & 1)
  140. length ++ ;
  141. psf_binheader_readf (psf, "j", length) ;
  142. break ;
  143. case SLCL_MARKER:
  144. psf_log_printf (psf, " %M\n (Offset, Next Offset, Type)\n", marker) ;
  145. slce_count = 0 ;
  146. break ;
  147. case SLCE_MARKER:
  148. { int len [4], indx ;
  149. psf_binheader_readf (psf, "E4444", &len [0], &len [1], &len [2], &len [3]) ;
  150. indx = ((len [3] & 0x0000FFFF) >> 8) & 3 ;
  151. if (len [2] == 1)
  152. { if (indx != 1)
  153. indx = 3 ; /* 2 cases, where next slice offset = 1 -> disabled & enabled/hidden */
  154. psf_log_printf (psf, " %M : (%6d, ?: 0x%X, %s)\n", marker, len [1], (len [3] & 0xFFFF0000) >> 16, marker_type [indx]) ;
  155. }
  156. else
  157. { slce_total += len [2] ;
  158. 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]) ;
  159. } ;
  160. slce_count ++ ;
  161. } ;
  162. break ;
  163. case SINF_MARKER:
  164. psf_binheader_readf (psf, "E4", &length) ;
  165. psf_log_printf (psf, " %M : %d\n", marker, length) ;
  166. psf_binheader_readf (psf, "E2", &n_channels) ;
  167. n_channels = (n_channels & 0x0000FF00) >> 8 ;
  168. psf_log_printf (psf, " Channels : %d\n", n_channels) ;
  169. psf_binheader_readf (psf, "E44", &psf->sf.samplerate, &frames) ;
  170. psf->sf.frames = frames ;
  171. psf_log_printf (psf, " Sample Rate : %d\n", psf->sf.samplerate) ;
  172. psf_log_printf (psf, " Frames : %D\n", psf->sf.frames) ;
  173. psf_binheader_readf (psf, "E4", &length) ;
  174. psf_log_printf (psf, " ??????????? : %d\n", length) ;
  175. psf_binheader_readf (psf, "E4", &length) ;
  176. psf_log_printf (psf, " ??????????? : %d\n", length) ;
  177. break ;
  178. case SDAT_MARKER:
  179. psf_binheader_readf (psf, "E4", &length) ;
  180. sdat_length = length ;
  181. /* Get the current offset. */
  182. psf->dataoffset = psf_binheader_readf (psf, NULL) ;
  183. if (psf->dataoffset + length != psf->filelength)
  184. psf_log_printf (psf, " %M : %d (should be %d)\n", marker, length, psf->dataoffset + psf->filelength) ;
  185. else
  186. psf_log_printf (psf, " %M : %d\n", marker, length) ;
  187. break ;
  188. default :
  189. psf_log_printf (psf, "Unknown marker : 0x%X %M", marker, marker) ;
  190. return -1003 ;
  191. break ;
  192. } ;
  193. /* SDAT always last marker in file. */
  194. if (marker == SDAT_MARKER)
  195. break ;
  196. } ;
  197. puts (psf->parselog.buf) ;
  198. puts ("-----------------------------------") ;
  199. printf ("SDAT length : %d\n", sdat_length) ;
  200. printf ("SLCE count : %d\n", slce_count) ;
  201. /* Hack for zero slice count. */
  202. if (slce_count == 0 && slce_total == 1)
  203. slce_total = frames ;
  204. printf ("SLCE samples : %d\n", slce_total) ;
  205. /* Two bytes per sample. */
  206. printf ("Comp Ratio : %f:1\n", (2.0 * slce_total * n_channels) / sdat_length) ;
  207. puts (" ") ;
  208. psf->parselog.buf [0] = 0 ;
  209. /* OK, have the header although not too sure what it all means. */
  210. psf->endian = SF_ENDIAN_BIG ;
  211. psf->datalength = psf->filelength - psf->dataoffset ;
  212. if (psf_fseek (psf, psf->dataoffset, SEEK_SET))
  213. return SFE_BAD_SEEK ;
  214. psf->sf.format = (SF_FORMAT_REX2 | SF_FORMAT_DWVW_12) ;
  215. psf->sf.channels = 1 ;
  216. psf->bytewidth = 2 ;
  217. psf->blockwidth = psf->sf.channels * psf->bytewidth ;
  218. if ((error = dwvw_init (psf, 16)))
  219. return error ;
  220. psf->container_close = rx2_close ;
  221. if (! psf->sf.frames && psf->blockwidth)
  222. psf->sf.frames = psf->datalength / psf->blockwidth ;
  223. /* All done. */
  224. return 0 ;
  225. } /* rx2_open */
  226. /*------------------------------------------------------------------------------
  227. */
  228. static int
  229. rx2_close (SF_PRIVATE *psf)
  230. {
  231. if (psf->file.mode == SFM_WRITE)
  232. { /* Now we know for certain the length of the file we can re-write
  233. ** correct values for the FORM, 8SVX and BODY chunks.
  234. */
  235. } ;
  236. return 0 ;
  237. } /* rx2_close */
  238. #endif