3 Copyright (C) 1998-2000, Michael Pruett <michael@68k.org>
4 Copyright (C) 2000, Silicon Graphics, Inc.
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
16 You should have received a copy of the GNU Library General Public
17 License along with this library; if not, write to the
18 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307 USA.
25 This file contains general utility routines for the Audio File
38 #include "audiofile.h"
41 #include "afinternal.h"
44 #include "compression.h"
46 #include "byteorder.h"
47 #include "aupvinternal.h"
49 extern const _PCMInfo _af_default_signed_integer_pcm_mappings
[];
50 extern const _PCMInfo _af_default_unsigned_integer_pcm_mappings
[];
51 extern const _PCMInfo _af_default_float_pcm_mapping
;
52 extern const _PCMInfo _af_default_double_pcm_mapping
;
54 extern const _CompressionUnit _af_compression
[];
57 _af_filesetup_ok and _af_filehandle_ok are sanity check routines
58 which are called at the beginning of every external subroutine.
60 bool _af_filesetup_ok (AFfilesetup setup
)
62 if (setup
== AF_NULL_FILESETUP
)
64 _af_error(AF_BAD_FILESETUP
, "null file setup");
67 if (setup
->valid
!= _AF_VALID_FILESETUP
)
69 _af_error(AF_BAD_FILESETUP
, "invalid file setup");
75 bool _af_filehandle_can_read (AFfilehandle file
)
77 if (file
->access
!= _AF_READ_ACCESS
)
79 _af_error(AF_BAD_NOREADACC
, "file not opened for read access");
86 bool _af_filehandle_can_write (AFfilehandle file
)
88 if (file
->access
!= _AF_WRITE_ACCESS
)
90 _af_error(AF_BAD_NOWRITEACC
, "file not opened for write access");
97 bool _af_filehandle_ok (AFfilehandle file
)
99 if (file
== AF_NULL_FILEHANDLE
)
101 _af_error(AF_BAD_FILEHANDLE
, "null file handle");
104 if (file
->valid
!= _AF_VALID_FILEHANDLE
)
106 _af_error(AF_BAD_FILEHANDLE
, "invalid file handle");
112 void *_af_malloc (size_t size
)
118 _af_error(AF_BAD_MALLOC
, "bad memory allocation size request %d", size
);
126 memset(p
, 0xff, size
);
131 _af_error(AF_BAD_MALLOC
, "allocation of %d bytes failed", size
);
138 char *_af_strdup (char *s
)
140 char *p
= malloc(strlen(s
) + 1);
148 void *_af_realloc (void *p
, size_t size
)
152 _af_error(AF_BAD_MALLOC
, "bad memory allocation size request %d", size
);
156 p
= realloc(p
, size
);
160 _af_error(AF_BAD_MALLOC
, "allocation of %d bytes failed", size
);
167 void *_af_calloc (size_t nmemb
, size_t size
)
171 if (nmemb
<= 0 || size
<= 0)
173 _af_error(AF_BAD_MALLOC
, "bad memory allocation size request "
174 "%d elements of %d bytes each", nmemb
, size
);
178 p
= calloc(nmemb
, size
);
182 _af_error(AF_BAD_MALLOC
, "allocation of %d bytes failed",
190 AUpvlist
_af_pv_long (long val
)
192 AUpvlist ret
= AUpvnew(1);
193 AUpvsetparam(ret
, 0, 0);
194 AUpvsetvaltype(ret
, 0, AU_PVTYPE_LONG
);
195 AUpvsetval(ret
, 0, &val
);
199 AUpvlist
_af_pv_double (double val
)
201 AUpvlist ret
= AUpvnew(1);
202 AUpvsetparam(ret
, 0, 0);
203 AUpvsetvaltype(ret
, 0, AU_PVTYPE_DOUBLE
);
204 AUpvsetval(ret
, 0, &val
);
208 AUpvlist
_af_pv_pointer (void *val
)
210 AUpvlist ret
= AUpvnew(1);
211 AUpvsetparam(ret
, 0, 0);
212 AUpvsetvaltype(ret
, 0, AU_PVTYPE_PTR
);
213 AUpvsetval(ret
, 0, &val
);
217 bool _af_pv_getlong (AUpvlist pvlist
, int param
, long *l
)
221 for (i
=0; i
<AUpvgetmaxitems(pvlist
); i
++)
225 AUpvgetparam(pvlist
, i
, &p
);
230 AUpvgetvaltype(pvlist
, i
, &t
);
232 /* Ensure that this parameter is of type AU_PVTYPE_LONG. */
233 if (t
!= AU_PVTYPE_LONG
)
236 AUpvgetval(pvlist
, i
, l
);
243 bool _af_pv_getdouble (AUpvlist pvlist
, int param
, double *d
)
247 for (i
=0; i
<AUpvgetmaxitems(pvlist
); i
++)
251 AUpvgetparam(pvlist
, i
, &p
);
256 AUpvgetvaltype(pvlist
, i
, &t
);
258 /* Ensure that this parameter is of type AU_PVTYPE_DOUBLE. */
259 if (t
!= AU_PVTYPE_DOUBLE
)
262 AUpvgetval(pvlist
, i
, d
);
269 bool _af_pv_getptr (AUpvlist pvlist
, int param
, void **v
)
273 for (i
=0; i
<AUpvgetmaxitems(pvlist
); i
++)
277 AUpvgetparam(pvlist
, i
, &p
);
282 AUpvgetvaltype(pvlist
, i
, &t
);
284 /* Ensure that this parameter is of type AU_PVTYPE_PTR. */
285 if (t
!= AU_PVTYPE_PTR
)
288 AUpvgetval(pvlist
, i
, v
);
295 _TrackSetup
*_af_filesetup_get_tracksetup (AFfilesetup setup
, int trackid
)
298 for (i
=0; i
<setup
->trackCount
; i
++)
300 if (setup
->tracks
[i
].id
== trackid
)
301 return &setup
->tracks
[i
];
304 _af_error(AF_BAD_TRACKID
, "bad track id %d", trackid
);
309 _Track
*_af_filehandle_get_track (AFfilehandle file
, int trackid
)
312 for (i
=0; i
<file
->trackCount
; i
++)
314 if (file
->tracks
[i
].id
== trackid
)
315 return &file
->tracks
[i
];
318 _af_error(AF_BAD_TRACKID
, "bad track id %d", trackid
);
323 int _af_format_sample_size_uncompressed (_AudioFormat
*format
, bool stretch3to4
)
327 switch (format
->sampleFormat
)
329 case AF_SAMPFMT_FLOAT
:
330 size
= sizeof (float);
332 case AF_SAMPFMT_DOUBLE
:
333 size
= sizeof (double);
336 size
= (int) (format
->sampleWidth
+ 7) / 8;
337 if (format
->compressionType
== AF_COMPRESSION_NONE
&&
338 size
== 3 && stretch3to4
)
346 float _af_format_sample_size (_AudioFormat
*fmt
, bool stretch3to4
)
348 int compressionIndex
;
351 compressionIndex
= _af_compression_index_from_id(fmt
->compressionType
);
352 squishFactor
= _af_compression
[compressionIndex
].squishFactor
;
354 return _af_format_sample_size_uncompressed(fmt
, stretch3to4
) /
358 int _af_format_frame_size_uncompressed (_AudioFormat
*fmt
, bool stretch3to4
)
360 return _af_format_sample_size_uncompressed(fmt
, stretch3to4
) *
364 float _af_format_frame_size (_AudioFormat
*fmt
, bool stretch3to4
)
366 int compressionIndex
;
369 compressionIndex
= _af_compression_index_from_id(fmt
->compressionType
);
370 squishFactor
= _af_compression
[compressionIndex
].squishFactor
;
372 return _af_format_frame_size_uncompressed(fmt
, stretch3to4
) /
377 Set the sampleFormat and sampleWidth fields in f, and set the
378 PCM info to the appropriate default values for the given sample
379 format and sample width.
381 status
_af_set_sample_format (_AudioFormat
*f
, int sampleFormat
, int sampleWidth
)
383 switch (sampleFormat
)
385 case AF_SAMPFMT_UNSIGNED
:
386 case AF_SAMPFMT_TWOSCOMP
:
387 if (sampleWidth
< 1 || sampleWidth
> 32)
389 _af_error(AF_BAD_SAMPFMT
,
390 "illegal sample width %d for integer data",
398 f
->sampleFormat
= sampleFormat
;
399 f
->sampleWidth
= sampleWidth
;
401 bytes
= _af_format_sample_size_uncompressed(f
, false);
403 if (sampleFormat
== AF_SAMPFMT_TWOSCOMP
)
404 f
->pcm
= _af_default_signed_integer_pcm_mappings
[bytes
];
406 f
->pcm
= _af_default_unsigned_integer_pcm_mappings
[bytes
];
410 case AF_SAMPFMT_FLOAT
:
411 f
->sampleFormat
= sampleFormat
;
413 f
->pcm
= _af_default_float_pcm_mapping
;
415 case AF_SAMPFMT_DOUBLE
:
416 f
->sampleFormat
= sampleFormat
;
417 f
->sampleWidth
= 64; /*for convenience */
418 f
->pcm
= _af_default_double_pcm_mapping
;
421 _af_error(AF_BAD_SAMPFMT
, "unknown sample format %d",
430 Verify the uniqueness of the nids ids given.
432 idname is the name of what the ids identify, as in "loop"
433 iderr is an error as in AF_BAD_LOOPID
435 bool _af_unique_ids (int *ids
, int nids
, char *idname
, int iderr
)
439 for (i
= 0; i
< nids
; i
++)
442 for (j
= 0; j
< i
; j
++)
443 if (ids
[i
] == ids
[j
])
445 _af_error(iderr
, "nonunique %s id %d",
454 status
af_read_uint32_be (uint32_t *value
, AFvirtualfile
*vf
)
458 if (af_fread(&v
, sizeof (v
), 1, vf
) != 1)
460 *value
= BENDIAN_TO_HOST_INT32(v
);
464 status
af_read_uint32_le (uint32_t *value
, AFvirtualfile
*vf
)
468 if (af_fread(&v
, sizeof (v
), 1, vf
) != 1)
470 *value
= LENDIAN_TO_HOST_INT32(v
);
474 status
af_read_uint16_be (uint16_t *value
, AFvirtualfile
*vf
)
478 if (af_fread(&v
, sizeof (v
), 1, vf
) != 1)
480 *value
= BENDIAN_TO_HOST_INT16(v
);
484 status
af_read_uint16_le (uint16_t *value
, AFvirtualfile
*vf
)
488 if (af_fread(&v
, sizeof (v
), 1, vf
) != 1)
490 *value
= LENDIAN_TO_HOST_INT16(v
);
494 status
af_read_uint8 (uint8_t *value
, AFvirtualfile
*vf
)
496 if (af_fread(value
, 1, 1, vf
) != 1)
501 status
af_write_uint32_be (const uint32_t *value
, AFvirtualfile
*vf
)
504 v
= HOST_TO_BENDIAN_INT32(*value
);
505 if (af_fwrite(&v
, sizeof (v
), 1, vf
) != 1)
510 status
af_write_uint32_le (const uint32_t *value
, AFvirtualfile
*vf
)
513 v
= HOST_TO_LENDIAN_INT32(*value
);
514 if (af_fwrite(&v
, sizeof (v
), 1, vf
) != 1)
519 status
af_write_uint16_be (const uint16_t *value
, AFvirtualfile
*vf
)
522 v
= HOST_TO_BENDIAN_INT16(*value
);
523 if (af_fwrite(&v
, sizeof (v
), 1, vf
) != 1)
528 status
af_write_uint16_le (const uint16_t *value
, AFvirtualfile
*vf
)
531 v
= HOST_TO_LENDIAN_INT16(*value
);
532 if (af_fwrite(&v
, sizeof (v
), 1, vf
) != 1)
537 status
af_write_uint8 (const uint8_t *value
, AFvirtualfile
*vf
)
539 if (af_fwrite(value
, 1, 1, vf
) != 1)
544 status
af_read_pstring (char s
[256], AFvirtualfile
*vf
)
547 /* Read the Pascal-style string containing the name. */
548 af_read_uint8(&length
, vf
);
549 af_fread(s
, length
, 1, vf
);
554 status
af_write_pstring (const char *s
, AFvirtualfile
*vf
)
556 size_t length
= strlen(s
);
559 uint8_t sizeByte
= (uint8_t) length
;
560 af_write_uint8(&sizeByte
, vf
);
561 af_fwrite(s
, sizeByte
, 1, vf
);
563 Add a pad byte if the length of the Pascal-style string
564 (including the size byte) is odd.
566 if ((length
% 2) == 0)
569 af_write_uint8(&zero
, vf
);