9ef10a91c5832e696a1d825043ae51c74f70d46a
2 ** Copyright (C) 2001-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
3 ** Copyright (C) 2004 Paavo Jumppanen
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU Lesser General Public License as published by
7 ** the Free Software Foundation; either version 2.1 of the License, or
8 ** (at your option) any later version.
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU Lesser General Public License for more details.
15 ** You should have received a copy of the GNU Lesser General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 ** The sd2 support implemented in this file was partially sponsored
22 ** (financially) by Paavo Jumppanen.
26 ** Documentation on the Mac resource fork was obtained here :
27 ** http://developer.apple.com/documentation/mac/MoreToolbox/MoreToolbox-99.html
41 /*------------------------------------------------------------------------------
45 #define Sd2f_MARKER MAKE_MARKER ('S', 'd', '2', 'f')
46 #define Sd2a_MARKER MAKE_MARKER ('S', 'd', '2', 'a')
47 #define ALCH_MARKER MAKE_MARKER ('A', 'L', 'C', 'H')
48 #define lsf1_MARKER MAKE_MARKER ('l', 's', 'f', '1')
50 #define STR_MARKER MAKE_MARKER ('S', 'T', 'R', ' ')
51 #define sdML_MARKER MAKE_MARKER ('s', 'd', 'M', 'L')
59 { unsigned char * rsrc_data
;
61 int need_to_free_rsrc_data
;
63 int data_offset
, data_length
;
64 int map_offset
, map_length
;
66 int type_count
, type_offset
;
69 int str_index
, str_count
;
73 /* All the above just to get these three. */
74 int sample_size
, sample_rate
, channels
;
85 /*------------------------------------------------------------------------------
86 * Private static functions.
89 static int sd2_close (SF_PRIVATE
*psf
) ;
91 static int sd2_parse_rsrc_fork (SF_PRIVATE
*psf
) ;
92 static int parse_str_rsrc (SF_PRIVATE
*psf
, SD2_RSRC
* rsrc
) ;
94 static int sd2_write_rsrc_fork (SF_PRIVATE
*psf
, int calc_length
) ;
96 /*------------------------------------------------------------------------------
101 sd2_open (SF_PRIVATE
*psf
)
102 { int subformat
, error
= 0, valid
;
104 /* SD2 is always big endian. */
105 psf
->endian
= SF_ENDIAN_BIG
;
107 if (psf
->file
.mode
== SFM_READ
|| (psf
->file
.mode
== SFM_RDWR
&& psf
->rsrclength
> 0))
108 { psf_use_rsrc (psf
, SF_TRUE
) ;
109 valid
= psf_file_valid (psf
) ;
110 psf_use_rsrc (psf
, SF_FALSE
) ;
112 { psf_log_printf (psf
, "sd2_open : psf->rsrc.filedes < 0\n") ;
113 return SFE_SD2_BAD_RSRC
;
116 error
= sd2_parse_rsrc_fork (psf
) ;
122 if ((SF_CONTAINER (psf
->sf
.format
)) != SF_FORMAT_SD2
)
123 { error
= SFE_BAD_OPEN_FORMAT
;
127 subformat
= SF_CODEC (psf
->sf
.format
) ;
128 psf
->dataoffset
= 0 ;
130 /* Only open and write the resource in RDWR mode is its current length is zero. */
131 if (psf
->file
.mode
== SFM_WRITE
|| (psf
->file
.mode
== SFM_RDWR
&& psf
->rsrclength
== 0))
132 { psf
->rsrc
.mode
= psf
->file
.mode
;
133 psf_open_rsrc (psf
) ;
135 error
= sd2_write_rsrc_fork (psf
, SF_FALSE
) ;
141 psf
->write_header
= NULL
;
144 psf
->container_close
= sd2_close
;
146 psf
->blockwidth
= psf
->bytewidth
* psf
->sf
.channels
;
149 { case SF_FORMAT_PCM_S8
: /* 8-bit linear PCM. */
150 case SF_FORMAT_PCM_16
: /* 16-bit linear PCM. */
151 case SF_FORMAT_PCM_24
: /* 24-bit linear PCM */
152 error
= pcm_init (psf
) ;
156 error
= SFE_UNIMPLEMENTED
;
160 psf_fseek (psf
, psf
->dataoffset
, SEEK_SET
) ;
164 /* Close the resource fork regardless. We won't need it again. */
165 psf_close_rsrc (psf
) ;
170 /*------------------------------------------------------------------------------
174 sd2_close (SF_PRIVATE
*psf
)
176 if (psf
->file
.mode
== SFM_WRITE
)
177 { /* Now we know for certain the audio_length of the file we can re-write
178 ** correct values for the FORM, 8SVX and BODY chunks.
186 /*------------------------------------------------------------------------------
190 write_char (unsigned char * data
, int offset
, char value
)
191 { data
[offset
] = value
;
195 write_short (unsigned char * data
, int offset
, short value
)
196 { data
[offset
] = value
>> 8 ;
197 data
[offset
+ 1] = value
;
201 write_int (unsigned char * data
, int offset
, int value
)
202 { data
[offset
] = value
>> 24 ;
203 data
[offset
+ 1] = value
>> 16 ;
204 data
[offset
+ 2] = value
>> 8 ;
205 data
[offset
+ 3] = value
;
209 write_marker (unsigned char * data
, int offset
, int value
)
211 if (CPU_IS_BIG_ENDIAN
)
212 { data
[offset
] = value
>> 24 ;
213 data
[offset
+ 1] = value
>> 16 ;
214 data
[offset
+ 2] = value
>> 8 ;
215 data
[offset
+ 3] = value
;
218 { data
[offset
] = value
;
219 data
[offset
+ 1] = value
>> 8 ;
220 data
[offset
+ 2] = value
>> 16 ;
221 data
[offset
+ 3] = value
>> 24 ;
226 write_str (unsigned char * data
, int offset
, const char * buffer
, int buffer_len
)
227 { memcpy (data
+ offset
, buffer
, buffer_len
) ;
231 sd2_write_rsrc_fork (SF_PRIVATE
*psf
, int UNUSED (calc_length
))
233 STR_RSRC str_rsrc
[] =
234 { { RSRC_STR
, 1000, "_sample-size", "", 0 },
235 { RSRC_STR
, 1001, "_sample-rate", "", 0 },
236 { RSRC_STR
, 1002, "_channels", "", 0 },
237 { RSRC_BIN
, 1000, "_Markers", "", 8 }
240 int k
, str_offset
, data_offset
, next_str
;
242 psf_use_rsrc (psf
, SF_TRUE
) ;
244 memset (&rsrc
, 0, sizeof (rsrc
)) ;
246 rsrc
.sample_rate
= psf
->sf
.samplerate
;
247 rsrc
.sample_size
= psf
->bytewidth
;
248 rsrc
.channels
= psf
->sf
.channels
;
250 rsrc
.rsrc_data
= psf
->header
;
251 rsrc
.rsrc_len
= sizeof (psf
->header
) ;
252 memset (rsrc
.rsrc_data
, 0xea, rsrc
.rsrc_len
) ;
254 snprintf (str_rsrc
[0].value
, sizeof (str_rsrc
[0].value
), "_%d", rsrc
.sample_size
) ;
255 snprintf (str_rsrc
[1].value
, sizeof (str_rsrc
[1].value
), "_%d.000000", rsrc
.sample_rate
) ;
256 snprintf (str_rsrc
[2].value
, sizeof (str_rsrc
[2].value
), "_%d", rsrc
.channels
) ;
258 for (k
= 0 ; k
< ARRAY_LEN (str_rsrc
) ; k
++)
259 { if (str_rsrc
[k
].value_len
== 0)
260 { str_rsrc
[k
].value_len
= strlen (str_rsrc
[k
].value
) ;
261 str_rsrc
[k
].value
[0] = str_rsrc
[k
].value_len
- 1 ;
264 /* Turn name string into a pascal string. */
265 str_rsrc
[k
].name
[0] = strlen (str_rsrc
[k
].name
) - 1 ;
268 rsrc
.data_offset
= 0x100 ;
271 ** Calculate data length :
272 ** length of strings, plus the length of the sdML chunk.
274 rsrc
.data_length
= 0 ;
275 for (k
= 0 ; k
< ARRAY_LEN (str_rsrc
) ; k
++)
276 rsrc
.data_length
+= str_rsrc
[k
].value_len
+ 4 ;
278 rsrc
.map_offset
= rsrc
.data_offset
+ rsrc
.data_length
;
280 /* Very start of resource fork. */
281 write_int (rsrc
.rsrc_data
, 0, rsrc
.data_offset
) ;
282 write_int (rsrc
.rsrc_data
, 4, rsrc
.map_offset
) ;
283 write_int (rsrc
.rsrc_data
, 8, rsrc
.data_length
) ;
285 write_char (rsrc
.rsrc_data
, 0x30, strlen (psf
->file
.name
.c
)) ;
286 write_str (rsrc
.rsrc_data
, 0x31, psf
->file
.name
.c
, strlen (psf
->file
.name
.c
)) ;
288 write_short (rsrc
.rsrc_data
, 0x50, 0) ;
289 write_marker (rsrc
.rsrc_data
, 0x52, Sd2f_MARKER
) ;
290 write_marker (rsrc
.rsrc_data
, 0x56, lsf1_MARKER
) ;
292 /* Very start of resource map. */
293 write_int (rsrc
.rsrc_data
, rsrc
.map_offset
+ 0, rsrc
.data_offset
) ;
294 write_int (rsrc
.rsrc_data
, rsrc
.map_offset
+ 4, rsrc
.map_offset
) ;
295 write_int (rsrc
.rsrc_data
, rsrc
.map_offset
+ 8, rsrc
.data_length
) ;
297 /* These I don't currently understand. */
299 { write_char (rsrc
.rsrc_data
, rsrc
.map_offset
+ 16, 1) ;
300 /* Next resource map. */
301 write_int (rsrc
.rsrc_data
, rsrc
.map_offset
+ 17, 0x12345678) ;
302 /* File ref number. */
303 write_short (rsrc
.rsrc_data
, rsrc
.map_offset
+ 21, 0xabcd) ;
304 /* Fork attributes. */
305 write_short (rsrc
.rsrc_data
, rsrc
.map_offset
+ 23, 0) ;
308 /* Resource type offset. */
309 rsrc
.type_offset
= rsrc
.map_offset
+ 30 ;
310 write_short (rsrc
.rsrc_data
, rsrc
.map_offset
+ 24, rsrc
.type_offset
- rsrc
.map_offset
- 2) ;
312 /* Type index max. */
313 rsrc
.type_count
= 2 ;
314 write_short (rsrc
.rsrc_data
, rsrc
.map_offset
+ 28, rsrc
.type_count
- 1) ;
316 rsrc
.item_offset
= rsrc
.type_offset
+ rsrc
.type_count
* 8 ;
318 rsrc
.str_count
= ARRAY_LEN (str_rsrc
) ;
319 rsrc
.string_offset
= rsrc
.item_offset
+ (rsrc
.str_count
+ 1) * 12 - rsrc
.map_offset
;
320 write_short (rsrc
.rsrc_data
, rsrc
.map_offset
+ 26, rsrc
.string_offset
) ;
322 /* Write 'STR ' resource type. */
324 write_marker (rsrc
.rsrc_data
, rsrc
.type_offset
, STR_MARKER
) ;
325 write_short (rsrc
.rsrc_data
, rsrc
.type_offset
+ 4, rsrc
.str_count
- 1) ;
326 write_short (rsrc
.rsrc_data
, rsrc
.type_offset
+ 6, 0x12) ;
328 /* Write 'sdML' resource type. */
329 write_marker (rsrc
.rsrc_data
, rsrc
.type_offset
+ 8, sdML_MARKER
) ;
330 write_short (rsrc
.rsrc_data
, rsrc
.type_offset
+ 12, 0) ;
331 write_short (rsrc
.rsrc_data
, rsrc
.type_offset
+ 14, 0x36) ;
333 str_offset
= rsrc
.map_offset
+ rsrc
.string_offset
;
335 data_offset
= rsrc
.data_offset
;
336 for (k
= 0 ; k
< ARRAY_LEN (str_rsrc
) ; k
++)
337 { write_str (rsrc
.rsrc_data
, str_offset
, str_rsrc
[k
].name
, strlen (str_rsrc
[k
].name
)) ;
339 write_short (rsrc
.rsrc_data
, rsrc
.item_offset
+ k
* 12, str_rsrc
[k
].id
) ;
340 write_short (rsrc
.rsrc_data
, rsrc
.item_offset
+ k
* 12 + 2, next_str
) ;
342 str_offset
+= strlen (str_rsrc
[k
].name
) ;
343 next_str
+= strlen (str_rsrc
[k
].name
) ;
345 write_int (rsrc
.rsrc_data
, rsrc
.item_offset
+ k
* 12 + 4, data_offset
- rsrc
.data_offset
) ;
347 write_int (rsrc
.rsrc_data
, data_offset
, str_rsrc
[k
].value_len
) ;
348 write_str (rsrc
.rsrc_data
, data_offset
+ 4, str_rsrc
[k
].value
, str_rsrc
[k
].value_len
) ;
349 data_offset
+= 4 + str_rsrc
[k
].value_len
;
352 /* Finally, calculate and set map length. */
353 rsrc
.map_length
= str_offset
- rsrc
.map_offset
;
354 write_int (rsrc
.rsrc_data
, 12, rsrc
.map_length
) ;
355 write_int (rsrc
.rsrc_data
, rsrc
.map_offset
+ 12, rsrc
.map_length
) ;
357 rsrc
.rsrc_len
= rsrc
.map_offset
+ rsrc
.map_length
;
359 psf_fwrite (rsrc
.rsrc_data
, rsrc
.rsrc_len
, 1, psf
) ;
361 psf_use_rsrc (psf
, SF_FALSE
) ;
367 } /* sd2_write_rsrc_fork */
369 /*------------------------------------------------------------------------------
373 read_char (const unsigned char * data
, int offset
)
374 { return data
[offset
] ;
378 read_short (const unsigned char * data
, int offset
)
379 { return (data
[offset
] << 8) + data
[offset
+ 1] ;
383 read_int (const unsigned char * data
, int offset
)
384 { return (data
[offset
] << 24) + (data
[offset
+ 1] << 16) + (data
[offset
+ 2] << 8) + data
[offset
+ 3] ;
388 read_marker (const unsigned char * data
, int offset
)
390 if (CPU_IS_BIG_ENDIAN
)
391 return (data
[offset
] << 24) + (data
[offset
+ 1] << 16) + (data
[offset
+ 2] << 8) + data
[offset
+ 3] ;
392 else if (CPU_IS_LITTLE_ENDIAN
)
393 return data
[offset
] + (data
[offset
+ 1] << 8) + (data
[offset
+ 2] << 16) + (data
[offset
+ 3] << 24) ;
399 read_str (const unsigned char * data
, int offset
, char * buffer
, int buffer_len
)
402 memset (buffer
, 0, buffer_len
) ;
404 for (k
= 0 ; k
< buffer_len
- 1 ; k
++)
405 { if (psf_isprint (data
[offset
+ k
]) == 0)
407 buffer
[k
] = data
[offset
+ k
] ;
413 sd2_parse_rsrc_fork (SF_PRIVATE
*psf
)
415 int k
, marker
, error
= 0 ;
417 psf_use_rsrc (psf
, SF_TRUE
) ;
419 memset (&rsrc
, 0, sizeof (rsrc
)) ;
421 rsrc
.rsrc_len
= psf_get_filelen (psf
) ;
422 psf_log_printf (psf
, "Resource length : %d (0x%04X)\n", rsrc
.rsrc_len
, rsrc
.rsrc_len
) ;
424 if (rsrc
.rsrc_len
> SIGNED_SIZEOF (psf
->header
))
425 { rsrc
.rsrc_data
= calloc (1, rsrc
.rsrc_len
) ;
426 rsrc
.need_to_free_rsrc_data
= SF_TRUE
;
429 rsrc
.rsrc_data
= psf
->header
;
431 /* Read in the whole lot. */
432 psf_fread (rsrc
.rsrc_data
, rsrc
.rsrc_len
, 1, psf
) ;
434 /* Reset the header storage because we have changed to the rsrcdes. */
435 psf
->headindex
= psf
->headend
= rsrc
.rsrc_len
;
437 rsrc
.data_offset
= read_int (rsrc
.rsrc_data
, 0) ;
438 rsrc
.map_offset
= read_int (rsrc
.rsrc_data
, 4) ;
439 rsrc
.data_length
= read_int (rsrc
.rsrc_data
, 8) ;
440 rsrc
.map_length
= read_int (rsrc
.rsrc_data
, 12) ;
442 if (rsrc
.data_offset
== 0x51607 && rsrc
.map_offset
== 0x20000)
443 { psf_log_printf (psf
, "Trying offset of 0x52 bytes.\n") ;
444 rsrc
.data_offset
= read_int (rsrc
.rsrc_data
, 0x52 + 0) + 0x52 ;
445 rsrc
.map_offset
= read_int (rsrc
.rsrc_data
, 0x52 + 4) + 0x52 ;
446 rsrc
.data_length
= read_int (rsrc
.rsrc_data
, 0x52 + 8) ;
447 rsrc
.map_length
= read_int (rsrc
.rsrc_data
, 0x52 + 12) ;
450 psf_log_printf (psf
, " data offset : 0x%04X\n map offset : 0x%04X\n"
451 " data length : 0x%04X\n map length : 0x%04X\n",
452 rsrc
.data_offset
, rsrc
.map_offset
, rsrc
.data_length
, rsrc
.map_length
) ;
454 if (rsrc
.data_offset
> rsrc
.rsrc_len
)
455 { psf_log_printf (psf
, "Error : rsrc.data_offset (%d, 0x%x) > len\n", rsrc
.data_offset
, rsrc
.data_offset
) ;
456 error
= SFE_SD2_BAD_DATA_OFFSET
;
457 goto parse_rsrc_fork_cleanup
;
460 if (rsrc
.map_offset
> rsrc
.rsrc_len
)
461 { psf_log_printf (psf
, "Error : rsrc.map_offset > len\n") ;
462 error
= SFE_SD2_BAD_MAP_OFFSET
;
463 goto parse_rsrc_fork_cleanup
;
466 if (rsrc
.data_length
> rsrc
.rsrc_len
)
467 { psf_log_printf (psf
, "Error : rsrc.data_length > len\n") ;
468 error
= SFE_SD2_BAD_DATA_LENGTH
;
469 goto parse_rsrc_fork_cleanup
;
472 if (rsrc
.map_length
> rsrc
.rsrc_len
)
473 { psf_log_printf (psf
, "Error : rsrc.map_length > len\n") ;
474 error
= SFE_SD2_BAD_MAP_LENGTH
;
475 goto parse_rsrc_fork_cleanup
;
478 if (rsrc
.data_offset
+ rsrc
.data_length
!= rsrc
.map_offset
|| rsrc
.map_offset
+ rsrc
.map_length
!= rsrc
.rsrc_len
)
479 { psf_log_printf (psf
, "Error : This does not look like a MacOSX resource fork.\n") ;
480 error
= SFE_SD2_BAD_RSRC
;
481 goto parse_rsrc_fork_cleanup
;
484 if (rsrc
.map_offset
+ 28 >= rsrc
.rsrc_len
)
485 { psf_log_printf (psf
, "Bad map offset (%d + 28 > %d).\n", rsrc
.map_offset
, rsrc
.rsrc_len
) ;
486 error
= SFE_SD2_BAD_RSRC
;
487 goto parse_rsrc_fork_cleanup
;
490 rsrc
.string_offset
= rsrc
.map_offset
+ read_short (rsrc
.rsrc_data
, rsrc
.map_offset
+ 26) ;
491 if (rsrc
.string_offset
> rsrc
.rsrc_len
)
492 { psf_log_printf (psf
, "Bad string offset (%d).\n", rsrc
.string_offset
) ;
493 error
= SFE_SD2_BAD_RSRC
;
494 goto parse_rsrc_fork_cleanup
;
497 rsrc
.type_offset
= rsrc
.map_offset
+ 30 ;
499 rsrc
.type_count
= read_short (rsrc
.rsrc_data
, rsrc
.map_offset
+ 28) + 1 ;
500 if (rsrc
.type_count
< 1)
501 { psf_log_printf (psf
, "Bad type count.\n") ;
502 error
= SFE_SD2_BAD_RSRC
;
503 goto parse_rsrc_fork_cleanup
;
506 rsrc
.item_offset
= rsrc
.type_offset
+ rsrc
.type_count
* 8 ;
507 if (rsrc
.item_offset
< 0 || rsrc
.item_offset
> rsrc
.rsrc_len
)
508 { psf_log_printf (psf
, "Bad item offset (%d).\n", rsrc
.item_offset
) ;
509 error
= SFE_SD2_BAD_RSRC
;
510 goto parse_rsrc_fork_cleanup
;
513 rsrc
.str_index
= -1 ;
514 for (k
= 0 ; k
< rsrc
.type_count
; k
++)
515 { marker
= read_marker (rsrc
.rsrc_data
, rsrc
.type_offset
+ k
* 8) ;
517 if (marker
== STR_MARKER
)
518 { rsrc
.str_index
= k
;
519 rsrc
.str_count
= read_short (rsrc
.rsrc_data
, rsrc
.type_offset
+ k
* 8 + 4) + 1 ;
520 error
= parse_str_rsrc (psf
, &rsrc
) ;
521 goto parse_rsrc_fork_cleanup
;
525 psf_log_printf (psf
, "No 'STR ' resource.\n") ;
526 error
= SFE_SD2_BAD_RSRC
;
528 parse_rsrc_fork_cleanup
:
530 psf_use_rsrc (psf
, SF_FALSE
) ;
532 if (rsrc
.need_to_free_rsrc_data
)
533 free (rsrc
.rsrc_data
) ;
536 } /* sd2_parse_rsrc_fork */
539 parse_str_rsrc (SF_PRIVATE
*psf
, SD2_RSRC
* rsrc
)
540 { char name
[32], value
[32] ;
541 int k
, str_offset
, rsrc_id
, data_offset
= 0, data_len
= 0 ;
543 psf_log_printf (psf
, "Finding parameters :\n") ;
545 str_offset
= rsrc
->string_offset
;
546 psf_log_printf (psf
, " Offset RsrcId dlen slen Value\n") ;
548 for (k
= 0 ; data_offset
+ data_len
< rsrc
->rsrc_len
; k
++)
551 slen
= read_char (rsrc
->rsrc_data
, str_offset
) ;
552 read_str (rsrc
->rsrc_data
, str_offset
+ 1, name
, SF_MIN (SIGNED_SIZEOF (name
), slen
+ 1)) ;
553 str_offset
+= slen
+ 1 ;
555 rsrc_id
= read_short (rsrc
->rsrc_data
, rsrc
->item_offset
+ k
* 12) ;
557 data_offset
= rsrc
->data_offset
+ read_int (rsrc
->rsrc_data
, rsrc
->item_offset
+ k
* 12 + 4) ;
558 if (data_offset
< 0 || data_offset
> rsrc
->rsrc_len
)
559 { psf_log_printf (psf
, "Exiting parser on data offset of %d.\n", data_offset
) ;
563 data_len
= read_int (rsrc
->rsrc_data
, data_offset
) ;
564 if (data_len
< 0 || data_len
> rsrc
->rsrc_len
)
565 { psf_log_printf (psf
, "Exiting parser on data length of %d.\n", data_len
) ;
569 slen
= read_char (rsrc
->rsrc_data
, data_offset
+ 4) ;
570 read_str (rsrc
->rsrc_data
, data_offset
+ 5, value
, SF_MIN (SIGNED_SIZEOF (value
), slen
+ 1)) ;
572 psf_log_printf (psf
, " 0x%04x %4d %4d %3d '%s'\n", data_offset
, rsrc_id
, data_len
, slen
, value
) ;
574 if (rsrc_id
== 1000 && rsrc
->sample_size
== 0)
575 rsrc
->sample_size
= strtol (value
, NULL
, 10) ;
576 else if (rsrc_id
== 1001 && rsrc
->sample_rate
== 0)
577 rsrc
->sample_rate
= strtol (value
, NULL
, 10) ;
578 else if (rsrc_id
== 1002 && rsrc
->channels
== 0)
579 rsrc
->channels
= strtol (value
, NULL
, 10) ;
582 psf_log_printf (psf
, "Found Parameters :\n") ;
583 psf_log_printf (psf
, " sample-size : %d\n", rsrc
->sample_size
) ;
584 psf_log_printf (psf
, " sample-rate : %d\n", rsrc
->sample_rate
) ;
585 psf_log_printf (psf
, " channels : %d\n", rsrc
->channels
) ;
587 if (rsrc
->sample_rate
<= 4 && rsrc
->sample_size
> 4)
590 psf_log_printf (psf
, "Geez!! Looks like sample rate and sample size got switched.\nCorrecting this screw up.\n") ;
591 temp
= rsrc
->sample_rate
;
592 rsrc
->sample_rate
= rsrc
->sample_size
;
593 rsrc
->sample_size
= temp
;
596 if (rsrc
->sample_rate
< 0)
597 { psf_log_printf (psf
, "Bad sample rate (%d)\n", rsrc
->sample_rate
) ;
598 return SFE_SD2_BAD_RSRC
;
601 if (rsrc
->channels
< 0)
602 { psf_log_printf (psf
, "Bad channel count (%d)\n", rsrc
->channels
) ;
603 return SFE_SD2_BAD_RSRC
;
606 psf
->sf
.samplerate
= rsrc
->sample_rate
;
607 psf
->sf
.channels
= rsrc
->channels
;
608 psf
->bytewidth
= rsrc
->sample_size
;
610 switch (rsrc
->sample_size
)
612 psf
->sf
.format
= SF_FORMAT_SD2
| SF_FORMAT_PCM_S8
;
616 psf
->sf
.format
= SF_FORMAT_SD2
| SF_FORMAT_PCM_16
;
620 psf
->sf
.format
= SF_FORMAT_SD2
| SF_FORMAT_PCM_24
;
624 psf_log_printf (psf
, "Bad sample size (%d)\n", rsrc
->sample_size
) ;
625 return SFE_SD2_BAD_SAMPLE_SIZE
;
628 psf_log_printf (psf
, "ok\n") ;
631 } /* parse_str_rsrc */