2 ** Copyright (C) 2001-2003 Erik de Castro Lopo <erikd@zip.com.au>
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.
29 #if (ENABLE_EXPERIMENTAL_CODE == 0)
32 sd2_open (SF_PRIVATE
*psf
)
34 return SFE_UNIMPLEMENTED
;
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 /*------------------------------------------------------------------------------
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
;
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
) ;
79 psf_log_printf (psf
, "Marker : %M\n"
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
) ;
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
) ;
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
) ;
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
;
162 psf_fseek (psf
, psf
->dataoffset
, SEEK_SET
) ;
164 psf
->close
= sd2_close
;
169 /*------------------------------------------------------------------------------
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.