rx2.c
上传用户:shw771010
上传日期:2022-01-05
资源大小:991k
文件大小:9k
- /*
- ** Copyright (C) 2001-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
- **
- ** This program is free software; you can redistribute it and/or modify
- ** it under the terms of the GNU Lesser General Public License as published by
- ** the Free Software Foundation; either version 2.1 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU Lesser General Public License for more details.
- **
- ** You should have received a copy of the GNU Lesser General Public License
- ** along with this program; if not, write to the Free Software
- ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
- #include "sfconfig.h"
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
- #include <stdarg.h>
- #include "sndfile.h"
- #include "sfendian.h"
- #include "common.h"
- #if (ENABLE_EXPERIMENTAL_CODE == 0)
- int
- rx2_open (SF_PRIVATE *psf)
- { if (psf)
- return SFE_UNIMPLEMENTED ;
- return 0 ;
- } /* rx2_open */
- #else
- /*------------------------------------------------------------------------------
- * Macros to handle big/little endian issues.
- */
- #define CAT_MARKER (MAKE_MARKER ('C', 'A', 'T', ' '))
- #define GLOB_MARKER (MAKE_MARKER ('G', 'L', 'O', 'B'))
- #define RECY_MARKER (MAKE_MARKER ('R', 'E', 'C', 'Y'))
- #define SLCL_MARKER (MAKE_MARKER ('S', 'L', 'C', 'L'))
- #define SLCE_MARKER (MAKE_MARKER ('S', 'L', 'C', 'E'))
- #define DEVL_MARKER (MAKE_MARKER ('D', 'E', 'V', 'L'))
- #define TRSH_MARKER (MAKE_MARKER ('T', 'R', 'S', 'H'))
- #define EQ_MARKER (MAKE_MARKER ('E', 'Q', ' ', ' '))
- #define COMP_MARKER (MAKE_MARKER ('C', 'O', 'M', 'P'))
- #define SINF_MARKER (MAKE_MARKER ('S', 'I', 'N', 'F'))
- #define SDAT_MARKER (MAKE_MARKER ('S', 'D', 'A', 'T'))
- /*------------------------------------------------------------------------------
- * Typedefs for file chunks.
- */
- /*------------------------------------------------------------------------------
- * Private static functions.
- */
- static int rx2_close (SF_PRIVATE *psf) ;
- /*------------------------------------------------------------------------------
- ** Public functions.
- */
- int
- rx2_open (SF_PRIVATE *psf)
- { static const char *marker_type [4] =
- { "Original Enabled", "Enabled Hidden",
- "Additional/PencilTool", "Disabled"
- } ;
- int error, marker, length, glob_offset, slce_count, frames ;
- int sdat_length = 0, slce_total = 0 ;
- int n_channels ;
- /* So far only doing read. */
- psf_binheader_readf (psf, "Epm4", 0, &marker, &length) ;
- if (marker != CAT_MARKER)
- { psf_log_printf (psf, "length : %dn", length) ;
- return -1000 ;
- } ;
- if (length != psf->filelength - 8)
- psf_log_printf (psf, "%M : %d (should be %d)n", marker, length, psf->filelength - 8) ;
- else
- psf_log_printf (psf, "%M : %dn", marker, length) ;
- /* 'REX2' marker */
- psf_binheader_readf (psf, "m", &marker) ;
- psf_log_printf (psf, "%M", marker) ;
- /* 'HEAD' marker */
- psf_binheader_readf (psf, "m", &marker) ;
- psf_log_printf (psf, "%Mn", marker) ;
- /* Grab 'GLOB' offset. */
- psf_binheader_readf (psf, "E4", &glob_offset) ;
- glob_offset += 0x14 ; /* Add the current file offset. */
- /* Jump to offset 0x30 */
- psf_binheader_readf (psf, "p", 0x30) ;
- /* Get name length */
- length = 0 ;
- psf_binheader_readf (psf, "1", &length) ;
- if (length >= SIGNED_SIZEOF (psf->u.cbuf))
- { psf_log_printf (psf, " Text : %d *** Error : Too sf_count_t!n") ;
- return -1001 ;
- }
- memset (psf->u.cbuf, 0, sizeof (psf->u.cbuf)) ;
- psf_binheader_readf (psf, "b", psf->u.cbuf, length) ;
- psf_log_printf (psf, " Text : "%s"n", psf->u.cbuf) ;
- /* Jump to GLOB offset position. */
- if (glob_offset & 1)
- glob_offset ++ ;
- psf_binheader_readf (psf, "p", glob_offset) ;
- slce_count = 0 ;
- /* GLOB */
- while (1)
- { psf_binheader_readf (psf, "m", &marker) ;
- if (marker != SLCE_MARKER && slce_count > 0)
- { psf_log_printf (psf, " SLCE count : %dn", slce_count) ;
- slce_count = 0 ;
- }
- switch (marker)
- { case GLOB_MARKER:
- psf_binheader_readf (psf, "E4", &length) ;
- psf_log_printf (psf, " %M : %dn", marker, length) ;
- psf_binheader_readf (psf, "j", length) ;
- break ;
- case RECY_MARKER:
- psf_binheader_readf (psf, "E4", &length) ;
- psf_log_printf (psf, " %M : %dn", marker, length) ;
- psf_binheader_readf (psf, "j", (length+1) & 0xFFFFFFFE) ; /* ?????? */
- break ;
- case CAT_MARKER:
- psf_binheader_readf (psf, "E4", &length) ;
- psf_log_printf (psf, " %M : %dn", marker, length) ;
- /*-psf_binheader_readf (psf, "j", length) ;-*/
- break ;
- case DEVL_MARKER:
- psf_binheader_readf (psf, "mE4", &marker, &length) ;
- psf_log_printf (psf, " DEVL%M : %dn", marker, length) ;
- if (length & 1)
- length ++ ;
- psf_binheader_readf (psf, "j", length) ;
- break ;
- case EQ_MARKER:
- case COMP_MARKER:
- psf_binheader_readf (psf, "E4", &length) ;
- psf_log_printf (psf, " %M : %dn", marker, length) ;
- /* This is weird!!!! why make this (length - 1) */
- if (length & 1)
- length ++ ;
- psf_binheader_readf (psf, "j", length) ;
- break ;
- case SLCL_MARKER:
- psf_log_printf (psf, " %Mn (Offset, Next Offset, Type)n", marker) ;
- slce_count = 0 ;
- break ;
- case SLCE_MARKER:
- { int len [4], indx ;
- psf_binheader_readf (psf, "E4444", &len [0], &len [1], &len [2], &len [3]) ;
- indx = ((len [3] & 0x0000FFFF) >> 8) & 3 ;
- if (len [2] == 1)
- { if (indx != 1)
- indx = 3 ; /* 2 cases, where next slice offset = 1 -> disabled & enabled/hidden */
- psf_log_printf (psf, " %M : (%6d, ?: 0x%X, %s)n", marker, len [1], (len [3] & 0xFFFF0000) >> 16, marker_type [indx]) ;
- }
- else
- { slce_total += len [2] ;
- 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]) ;
- } ;
- slce_count ++ ;
- } ;
- break ;
- case SINF_MARKER:
- psf_binheader_readf (psf, "E4", &length) ;
- psf_log_printf (psf, " %M : %dn", marker, length) ;
- psf_binheader_readf (psf, "E2", &n_channels) ;
- n_channels = (n_channels & 0x0000FF00) >> 8 ;
- psf_log_printf (psf, " Channels : %dn", n_channels) ;
- psf_binheader_readf (psf, "E44", &psf->sf.samplerate, &frames) ;
- psf->sf.frames = frames ;
- psf_log_printf (psf, " Sample Rate : %dn", psf->sf.samplerate) ;
- psf_log_printf (psf, " Frames : %Dn", psf->sf.frames) ;
- psf_binheader_readf (psf, "E4", &length) ;
- psf_log_printf (psf, " ??????????? : %dn", length) ;
- psf_binheader_readf (psf, "E4", &length) ;
- psf_log_printf (psf, " ??????????? : %dn", length) ;
- break ;
- case SDAT_MARKER:
- psf_binheader_readf (psf, "E4", &length) ;
- sdat_length = length ;
- /* Get the current offset. */
- psf->dataoffset = psf_binheader_readf (psf, NULL) ;
- if (psf->dataoffset + length != psf->filelength)
- psf_log_printf (psf, " %M : %d (should be %d)n", marker, length, psf->dataoffset + psf->filelength) ;
- else
- psf_log_printf (psf, " %M : %dn", marker, length) ;
- break ;
- default :
- psf_log_printf (psf, "Unknown marker : 0x%X %M", marker, marker) ;
- return -1003 ;
- break ;
- } ;
- /* SDAT always last marker in file. */
- if (marker == SDAT_MARKER)
- break ;
- } ;
- puts (psf->logbuffer) ;
- puts ("-----------------------------------") ;
- printf ("SDAT length : %dn", sdat_length) ;
- printf ("SLCE count : %dn", slce_count) ;
- /* Hack for zero slice count. */
- if (slce_count == 0 && slce_total == 1)
- slce_total = frames ;
- printf ("SLCE samples : %dn", slce_total) ;
- /* Two bytes per sample. */
- printf ("Comp Ratio : %f:1n", (2.0 * slce_total * n_channels) / sdat_length) ;
- puts (" ") ;
- psf->logbuffer [0] = 0 ;
- /* OK, have the header although not too sure what it all means. */
- psf->endian = SF_ENDIAN_BIG ;
- psf->datalength = psf->filelength - psf->dataoffset ;
- if (psf_fseek (psf, psf->dataoffset, SEEK_SET))
- return SFE_BAD_SEEK ;
- psf->sf.format = (SF_FORMAT_REX2 | SF_FORMAT_DWVW_12) ;
- psf->sf.channels = 1 ;
- psf->bytewidth = 2 ;
- psf->blockwidth = psf->sf.channels * psf->bytewidth ;
- if ((error = dwvw_init (psf, 16)))
- return error ;
- psf->container_close = rx2_close ;
- if (! psf->sf.frames && psf->blockwidth)
- psf->sf.frames = psf->datalength / psf->blockwidth ;
- /* All done. */
- return 0 ;
- } /* rx2_open */
- /*------------------------------------------------------------------------------
- */
- static int
- rx2_close (SF_PRIVATE *psf)
- {
- if (psf->file.mode == SFM_WRITE)
- { /* Now we know for certain the length of the file we can re-write
- ** correct values for the FORM, 8SVX and BODY chunks.
- */
- } ;
- return 0 ;
- } /* rx2_close */
- #endif