r663: This commit was generated by cvs2svn to compensate for changes in r662,
[cinelerra_cv.git] / libsndfile / src / sd2.c
blobd34092304ac1b559e5d1d547366d603634941c2e
1 /*
2 ** Copyright (C) 2001-2003 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.
19 #include <stdio.h>
20 #include <unistd.h>
21 #include <string.h>
23 #include "sndfile.h"
24 #include "config.h"
25 #include "sfendian.h"
26 #include "common.h"
29 #if (ENABLE_EXPERIMENTAL_CODE == 0)
31 int
32 sd2_open (SF_PRIVATE *psf)
33 { if (psf)
34 return SFE_UNIMPLEMENTED ;
35 return (psf && 0) ;
36 } /* sd2_open */
38 #else
40 /*------------------------------------------------------------------------------
41 * Macros to handle big/little endian issues.
44 #define Sd2f_MARKER MAKE_MARKER ('S', 'd', '2', 'f')
46 /*------------------------------------------------------------------------------
47 * Typedefs for file chunks.
52 /*------------------------------------------------------------------------------
53 * Private static functions.
56 static int sd2_close (SF_PRIVATE *psf) ;
58 /*------------------------------------------------------------------------------
59 ** Public functions.
62 int
63 sd2_open (SF_PRIVATE *psf)
64 { int marker, software, rsrc_offset, len ;
65 int rsrc_data_offset, rsrc_map_offset, rsrc_data_length, rsrc_map_length ;
66 char slen ;
67 float srate ;
69 /* Read only so far. */
71 psf_binheader_readf (psf, "Epmmj", 0x41, &marker, &software, 14) ;
73 if (marker != Sd2f_MARKER)
74 { printf ("Whoops!!!\n") ;
75 puts (psf->logbuffer) ;
76 return SFE_INTERNAL ;
77 } ;
79 psf_log_printf (psf, "Marker : %M\n"
80 "Software : %M\n",
81 marker, software) ;
83 /* This seems to be a constant for binhex files. */
84 psf->dataoffset = 0x80 ;
86 /* All SD2 files are big endian. */
87 psf->endian= SF_ENDIAN_BIG ;
90 ** Resource header info from:
91 ** http://developer.apple.com/techpubs/mac/MoreToolbox/MoreToolbox-99.html
94 rsrc_offset = psf->datalength + psf->dataoffset ;
95 if (rsrc_offset & 0x7F)
96 rsrc_offset = rsrc_offset - (rsrc_offset & 0x7F) + psf->dataoffset ;
98 psf_log_printf (psf, "Resource offset : 0x%X\n", rsrc_offset) ;
100 /* Jump to the rsrc_offset fork section. */
101 psf_binheader_readf (psf, "Ep", rsrc_offset) ;
103 psf_binheader_readf (psf, "E4444", &rsrc_data_offset, &rsrc_map_offset, &rsrc_data_length, &rsrc_map_length) ;
105 rsrc_data_offset += rsrc_offset ;
106 rsrc_map_offset += rsrc_offset ;
108 psf_log_printf (psf, " data offset : 0x%X\n"
109 " map offset : 0x%X\n"
110 " data length : 0x%X\n"
111 " map length : 0x%X\n",
113 rsrc_data_offset, rsrc_map_offset, rsrc_data_length, rsrc_map_length) ;
115 if (rsrc_data_offset + rsrc_data_length > rsrc_map_offset || rsrc_map_offset + rsrc_map_length > psf->filelength)
116 { puts ("##############################") ;
117 puts (psf->logbuffer) ;
118 puts ("##############################") ;
119 return SFE_INTERNAL ;
122 memset (psf->buffer, 0, sizeof (psf->buffer)) ;
124 psf_binheader_readf (psf, "Ep41", rsrc_data_offset, &len, &slen) ;
125 if (slen + 1 == len)
126 { psf_binheader_readf (psf, "Eb", psf->buffer, len - 1) ;
127 ((char*) psf->buffer) [len - 1] = 0 ;
128 if (sscanf ((char*) psf->buffer, "%d", &len) == 1)
129 psf->bytewidth = len ;
132 psf_binheader_readf (psf, "E41", &len, &slen) ;
133 if (slen + 1 == len)
134 { psf_binheader_readf (psf, "Eb", psf->buffer, len - 1) ;
135 ((char*) psf->buffer) [len - 1] = 0 ;
136 if (sscanf ((char*) psf->buffer, "%f", &srate) == 1)
137 psf->sf.samplerate = srate ;
140 psf_binheader_readf (psf, "E41", &len, &slen) ;
141 if (slen + 1 == len)
142 { psf_binheader_readf (psf, "Eb", psf->buffer, len - 1) ;
143 ((char*) psf->buffer) [len - 1] = 0 ;
144 if (sscanf ((char*) psf->buffer, "%d", &len) == 1)
145 psf->sf.channels = len ;
148 psf_log_printf (psf, " byte width : %d\n", psf->bytewidth) ;
149 psf_log_printf (psf, " sample rate : %d\n", psf->sf.samplerate) ;
150 psf_log_printf (psf, " channels : %d\n", psf->sf.channels) ;
152 if (psf->bytewidth == 2)
153 { psf->sf.format = SF_FORMAT_SD2 | SF_FORMAT_PCM_16 ;
155 psf->blockwidth = psf->bytewidth * psf->sf.channels ;
157 psf->sf.frames = psf->datalength / psf->blockwidth ;
160 pcm_init (psf) ;
162 psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
164 psf->close = sd2_close ;
166 return 0 ;
167 } /* sd2_open */
169 /*------------------------------------------------------------------------------
172 static int
173 sd2_close (SF_PRIVATE *psf)
175 if (psf->mode == SFM_WRITE)
176 { /* Now we know for certain the audio_length of the file we can re-write
177 ** correct values for the FORM, 8SVX and BODY chunks.
182 return 0 ;
183 } /* sd2_close */
185 #endif