2 ** Copyright (C) 2001-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
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.
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.
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.
30 #if (ENABLE_EXPERIMENTAL_CODE == 0)
33 rx2_open (SF_PRIVATE
*psf
)
35 return SFE_UNIMPLEMENTED
;
41 /*------------------------------------------------------------------------------
42 * Macros to handle big/little endian issues.
45 #define CAT_MARKER (MAKE_MARKER ('C', 'A', 'T', ' '))
46 #define GLOB_MARKER (MAKE_MARKER ('G', 'L', 'O', 'B'))
48 #define RECY_MARKER (MAKE_MARKER ('R', 'E', 'C', 'Y'))
50 #define SLCL_MARKER (MAKE_MARKER ('S', 'L', 'C', 'L'))
51 #define SLCE_MARKER (MAKE_MARKER ('S', 'L', 'C', 'E'))
53 #define DEVL_MARKER (MAKE_MARKER ('D', 'E', 'V', 'L'))
54 #define TRSH_MARKER (MAKE_MARKER ('T', 'R', 'S', 'H'))
56 #define EQ_MARKER (MAKE_MARKER ('E', 'Q', ' ', ' '))
57 #define COMP_MARKER (MAKE_MARKER ('C', 'O', 'M', 'P'))
59 #define SINF_MARKER (MAKE_MARKER ('S', 'I', 'N', 'F'))
60 #define SDAT_MARKER (MAKE_MARKER ('S', 'D', 'A', 'T'))
62 /*------------------------------------------------------------------------------
63 * Typedefs for file chunks.
67 /*------------------------------------------------------------------------------
68 * Private static functions.
70 static int rx2_close (SF_PRIVATE
*psf
) ;
72 /*------------------------------------------------------------------------------
77 rx2_open (SF_PRIVATE
*psf
)
78 { static const char *marker_type
[4] =
79 { "Original Enabled", "Enabled Hidden",
80 "Additional/PencilTool", "Disabled"
83 int error
, marker
, length
, glob_offset
, slce_count
, frames
;
85 int sdat_length
= 0, slce_total
= 0 ;
90 /* So far only doing read. */
92 psf_binheader_readf (psf
, "Epm4", 0, &marker
, &length
) ;
94 if (marker
!= CAT_MARKER
)
95 { psf_log_printf (psf
, "length : %d\n", length
) ;
99 if (length
!= psf
->filelength
- 8)
100 psf_log_printf (psf
, "%M : %d (should be %d)\n", marker
, length
, psf
->filelength
- 8) ;
102 psf_log_printf (psf
, "%M : %d\n", marker
, length
) ;
105 psf_binheader_readf (psf
, "m", &marker
) ;
106 psf_log_printf (psf
, "%M", marker
) ;
109 psf_binheader_readf (psf
, "m", &marker
) ;
110 psf_log_printf (psf
, "%M\n", marker
) ;
112 /* Grab 'GLOB' offset. */
113 psf_binheader_readf (psf
, "E4", &glob_offset
) ;
114 glob_offset
+= 0x14 ; /* Add the current file offset. */
116 /* Jump to offset 0x30 */
117 psf_binheader_readf (psf
, "p", 0x30) ;
119 /* Get name length */
121 psf_binheader_readf (psf
, "1", &length
) ;
122 if (length
>= SIGNED_SIZEOF (psf
->u
.cbuf
))
123 { psf_log_printf (psf
, " Text : %d *** Error : Too sf_count_t!\n") ;
127 memset (psf
->u
.cbuf
, 0, sizeof (psf
->u
.cbuf
)) ;
128 psf_binheader_readf (psf
, "b", psf
->u
.cbuf
, length
) ;
129 psf_log_printf (psf
, " Text : \"%s\"\n", psf
->u
.cbuf
) ;
131 /* Jump to GLOB offset position. */
135 psf_binheader_readf (psf
, "p", glob_offset
) ;
140 { psf_binheader_readf (psf
, "m", &marker
) ;
142 if (marker
!= SLCE_MARKER
&& slce_count
> 0)
143 { psf_log_printf (psf
, " SLCE count : %d\n", slce_count
) ;
148 psf_binheader_readf (psf
, "E4", &length
) ;
149 psf_log_printf (psf
, " %M : %d\n", marker
, length
) ;
150 psf_binheader_readf (psf
, "j", length
) ;
154 psf_binheader_readf (psf
, "E4", &length
) ;
155 psf_log_printf (psf
, " %M : %d\n", marker
, length
) ;
156 psf_binheader_readf (psf
, "j", (length
+1) & 0xFFFFFFFE) ; /* ?????? */
160 psf_binheader_readf (psf
, "E4", &length
) ;
161 psf_log_printf (psf
, " %M : %d\n", marker
, length
) ;
162 /*-psf_binheader_readf (psf, "j", length) ;-*/
166 psf_binheader_readf (psf
, "mE4", &marker
, &length
) ;
167 psf_log_printf (psf
, " DEVL%M : %d\n", marker
, length
) ;
170 psf_binheader_readf (psf
, "j", length
) ;
175 psf_binheader_readf (psf
, "E4", &length
) ;
176 psf_log_printf (psf
, " %M : %d\n", marker
, length
) ;
177 /* This is weird!!!! why make this (length - 1) */
180 psf_binheader_readf (psf
, "j", length
) ;
184 psf_log_printf (psf
, " %M\n (Offset, Next Offset, Type)\n", marker
) ;
189 { int len
[4], indx
;
191 psf_binheader_readf (psf
, "E4444", &len
[0], &len
[1], &len
[2], &len
[3]) ;
193 indx
= ((len
[3] & 0x0000FFFF) >> 8) & 3 ;
197 indx
= 3 ; /* 2 cases, where next slice offset = 1 -> disabled & enabled/hidden */
199 psf_log_printf (psf
, " %M : (%6d, ?: 0x%X, %s)\n", marker
, len
[1], (len
[3] & 0xFFFF0000) >> 16, marker_type
[indx
]) ;
202 { slce_total
+= len
[2] ;
204 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
]) ;
212 psf_binheader_readf (psf
, "E4", &length
) ;
213 psf_log_printf (psf
, " %M : %d\n", marker
, length
) ;
215 psf_binheader_readf (psf
, "E2", &n_channels
) ;
216 n_channels
= (n_channels
& 0x0000FF00) >> 8 ;
217 psf_log_printf (psf
, " Channels : %d\n", n_channels
) ;
219 psf_binheader_readf (psf
, "E44", &psf
->sf
.samplerate
, &frames
) ;
220 psf
->sf
.frames
= frames
;
221 psf_log_printf (psf
, " Sample Rate : %d\n", psf
->sf
.samplerate
) ;
222 psf_log_printf (psf
, " Frames : %D\n", psf
->sf
.frames
) ;
224 psf_binheader_readf (psf
, "E4", &length
) ;
225 psf_log_printf (psf
, " ??????????? : %d\n", length
) ;
227 psf_binheader_readf (psf
, "E4", &length
) ;
228 psf_log_printf (psf
, " ??????????? : %d\n", length
) ;
232 psf_binheader_readf (psf
, "E4", &length
) ;
234 sdat_length
= length
;
236 /* Get the current offset. */
237 psf
->dataoffset
= psf_binheader_readf (psf
, NULL
) ;
239 if (psf
->dataoffset
+ length
!= psf
->filelength
)
240 psf_log_printf (psf
, " %M : %d (should be %d)\n", marker
, length
, psf
->dataoffset
+ psf
->filelength
) ;
242 psf_log_printf (psf
, " %M : %d\n", marker
, length
) ;
246 psf_log_printf (psf
, "Unknown marker : 0x%X %M", marker
, marker
) ;
251 /* SDAT always last marker in file. */
252 if (marker
== SDAT_MARKER
)
256 puts (psf
->logbuffer
) ;
257 puts ("-----------------------------------") ;
259 printf ("SDAT length : %d\n", sdat_length
) ;
260 printf ("SLCE count : %d\n", slce_count
) ;
262 /* Hack for zero slice count. */
263 if (slce_count
== 0 && slce_total
== 1)
264 slce_total
= frames
;
266 printf ("SLCE samples : %d\n", slce_total
) ;
268 /* Two bytes per sample. */
269 printf ("Comp Ratio : %f:1\n", (2.0 * slce_total
* n_channels
) / sdat_length
) ;
273 psf
->logbuffer
[0] = 0 ;
275 /* OK, have the header although not too sure what it all means. */
277 psf
->endian
= SF_ENDIAN_BIG
;
279 psf
->datalength
= psf
->filelength
- psf
->dataoffset
;
281 if (psf_fseek (psf
, psf
->dataoffset
, SEEK_SET
))
282 return SFE_BAD_SEEK
;
284 psf
->sf
.format
= (SF_FORMAT_REX2
| SF_FORMAT_DWVW_12
) ;
286 psf
->sf
.channels
= 1 ;
288 psf
->blockwidth
= psf
->sf
.channels
* psf
->bytewidth
;
290 if ((error
= dwvw_init (psf
, 16)))
293 psf
->container_close
= rx2_close
;
295 if (! psf
->sf
.frames
&& psf
->blockwidth
)
296 psf
->sf
.frames
= psf
->datalength
/ psf
->blockwidth
;
303 /*------------------------------------------------------------------------------
307 rx2_close (SF_PRIVATE
*psf
)
309 if (psf
->file
.mode
== SFM_WRITE
)
310 { /* Now we know for certain the length of the file we can re-write
311 ** correct values for the FORM, 8SVX and BODY chunks.