(Metux) autogen.sh: not running ./configure anymore (breaks certain distro builders)
[mirror-ossqm-audiofile.git] / libaudiofile / util.c
blobf8246e8f6808ff65184c88dfb1f48c090d97ccd8
1 /*
2 Audio File Library
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.
23 util.c
25 This file contains general utility routines for the Audio File
26 Library.
29 #ifdef HAVE_CONFIG_H
30 #include <config.h>
31 #endif
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <assert.h>
38 #include "audiofile.h"
39 #include "aupvlist.h"
41 #include "afinternal.h"
42 #include "util.h"
43 #include "units.h"
44 #include "compression.h"
45 #include "modules.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");
65 return false;
67 if (setup->valid != _AF_VALID_FILESETUP)
69 _af_error(AF_BAD_FILESETUP, "invalid file setup");
70 return false;
72 return true;
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");
80 return false;
83 return true;
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");
91 return false;
94 return true;
97 bool _af_filehandle_ok (AFfilehandle file)
99 if (file == AF_NULL_FILEHANDLE)
101 _af_error(AF_BAD_FILEHANDLE, "null file handle");
102 return false;
104 if (file->valid != _AF_VALID_FILEHANDLE)
106 _af_error(AF_BAD_FILEHANDLE, "invalid file handle");
107 return false;
109 return true;
112 void *_af_malloc (size_t size)
114 void *p;
116 if (size <= 0)
118 _af_error(AF_BAD_MALLOC, "bad memory allocation size request %d", size);
119 return NULL;
122 p = malloc(size);
124 #ifdef AF_DEBUG
125 if (p)
126 memset(p, 0xff, size);
127 #endif
129 if (p == NULL)
131 _af_error(AF_BAD_MALLOC, "allocation of %d bytes failed", size);
132 return NULL;
135 return p;
138 char *_af_strdup (char *s)
140 char *p = malloc(strlen(s) + 1);
142 if (p)
143 strcpy(p, s);
145 return p;
148 void *_af_realloc (void *p, size_t size)
150 if (size <= 0)
152 _af_error(AF_BAD_MALLOC, "bad memory allocation size request %d", size);
153 return NULL;
156 p = realloc(p, size);
158 if (p == NULL)
160 _af_error(AF_BAD_MALLOC, "allocation of %d bytes failed", size);
161 return NULL;
164 return p;
167 void *_af_calloc (size_t nmemb, size_t size)
169 void *p;
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);
175 return NULL;
178 p = calloc(nmemb, size);
180 if (p == NULL)
182 _af_error(AF_BAD_MALLOC, "allocation of %d bytes failed",
183 nmemb*size);
184 return NULL;
187 return p;
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);
196 return ret;
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);
205 return ret;
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);
214 return ret;
217 bool _af_pv_getlong (AUpvlist pvlist, int param, long *l)
219 int i;
221 for (i=0; i<AUpvgetmaxitems(pvlist); i++)
223 int p, t;
225 AUpvgetparam(pvlist, i, &p);
227 if (p != param)
228 continue;
230 AUpvgetvaltype(pvlist, i, &t);
232 /* Ensure that this parameter is of type AU_PVTYPE_LONG. */
233 if (t != AU_PVTYPE_LONG)
234 return false;
236 AUpvgetval(pvlist, i, l);
237 return true;
240 return false;
243 bool _af_pv_getdouble (AUpvlist pvlist, int param, double *d)
245 int i;
247 for (i=0; i<AUpvgetmaxitems(pvlist); i++)
249 int p, t;
251 AUpvgetparam(pvlist, i, &p);
253 if (p != param)
254 continue;
256 AUpvgetvaltype(pvlist, i, &t);
258 /* Ensure that this parameter is of type AU_PVTYPE_DOUBLE. */
259 if (t != AU_PVTYPE_DOUBLE)
260 return false;
262 AUpvgetval(pvlist, i, d);
263 return true;
266 return false;
269 bool _af_pv_getptr (AUpvlist pvlist, int param, void **v)
271 int i;
273 for (i=0; i<AUpvgetmaxitems(pvlist); i++)
275 int p, t;
277 AUpvgetparam(pvlist, i, &p);
279 if (p != param)
280 continue;
282 AUpvgetvaltype(pvlist, i, &t);
284 /* Ensure that this parameter is of type AU_PVTYPE_PTR. */
285 if (t != AU_PVTYPE_PTR)
286 return false;
288 AUpvgetval(pvlist, i, v);
289 return true;
292 return false;
295 _TrackSetup *_af_filesetup_get_tracksetup (AFfilesetup setup, int trackid)
297 int i;
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);
306 return NULL;
309 _Track *_af_filehandle_get_track (AFfilehandle file, int trackid)
311 int i;
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);
320 return NULL;
323 int _af_format_sample_size_uncompressed (_AudioFormat *format, bool stretch3to4)
325 int size = 0;
327 switch (format->sampleFormat)
329 case AF_SAMPFMT_FLOAT:
330 size = sizeof (float);
331 break;
332 case AF_SAMPFMT_DOUBLE:
333 size = sizeof (double);
334 break;
335 default:
336 size = (int) (format->sampleWidth + 7) / 8;
337 if (format->compressionType == AF_COMPRESSION_NONE &&
338 size == 3 && stretch3to4)
339 size = 4;
340 break;
343 return size;
346 float _af_format_sample_size (_AudioFormat *fmt, bool stretch3to4)
348 int compressionIndex;
349 float squishFactor;
351 compressionIndex = _af_compression_index_from_id(fmt->compressionType);
352 squishFactor = _af_compression[compressionIndex].squishFactor;
354 return _af_format_sample_size_uncompressed(fmt, stretch3to4) /
355 squishFactor;
358 int _af_format_frame_size_uncompressed (_AudioFormat *fmt, bool stretch3to4)
360 return _af_format_sample_size_uncompressed(fmt, stretch3to4) *
361 fmt->channelCount;
364 float _af_format_frame_size (_AudioFormat *fmt, bool stretch3to4)
366 int compressionIndex;
367 float squishFactor;
369 compressionIndex = _af_compression_index_from_id(fmt->compressionType);
370 squishFactor = _af_compression[compressionIndex].squishFactor;
372 return _af_format_frame_size_uncompressed(fmt, stretch3to4) /
373 squishFactor;
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",
391 sampleWidth);
392 return AF_FAIL;
394 else
396 int bytes;
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];
405 else
406 f->pcm = _af_default_unsigned_integer_pcm_mappings[bytes];
408 break;
410 case AF_SAMPFMT_FLOAT:
411 f->sampleFormat = sampleFormat;
412 f->sampleWidth = 32;
413 f->pcm = _af_default_float_pcm_mapping;
414 break;
415 case AF_SAMPFMT_DOUBLE:
416 f->sampleFormat = sampleFormat;
417 f->sampleWidth = 64; /*for convenience */
418 f->pcm = _af_default_double_pcm_mapping;
419 break;
420 default:
421 _af_error(AF_BAD_SAMPFMT, "unknown sample format %d",
422 sampleFormat);
423 return AF_FAIL;
426 return AF_SUCCEED;
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)
437 int i;
439 for (i = 0; i < nids; i++)
441 int j;
442 for (j = 0; j < i; j++)
443 if (ids[i] == ids[j])
445 _af_error(iderr, "nonunique %s id %d",
446 idname, ids[i]);
447 return false;
451 return true;
454 status af_read_uint32_be (uint32_t *value, AFvirtualfile *vf)
456 uint32_t v;
458 if (af_fread(&v, sizeof (v), 1, vf) != 1)
459 return AF_FAIL;
460 *value = BENDIAN_TO_HOST_INT32(v);
461 return AF_SUCCEED;
464 status af_read_uint32_le (uint32_t *value, AFvirtualfile *vf)
466 uint32_t v;
468 if (af_fread(&v, sizeof (v), 1, vf) != 1)
469 return AF_FAIL;
470 *value = LENDIAN_TO_HOST_INT32(v);
471 return AF_SUCCEED;
474 status af_read_uint16_be (uint16_t *value, AFvirtualfile *vf)
476 uint16_t v;
478 if (af_fread(&v, sizeof (v), 1, vf) != 1)
479 return AF_FAIL;
480 *value = BENDIAN_TO_HOST_INT16(v);
481 return AF_SUCCEED;
484 status af_read_uint16_le (uint16_t *value, AFvirtualfile *vf)
486 uint16_t v;
488 if (af_fread(&v, sizeof (v), 1, vf) != 1)
489 return AF_FAIL;
490 *value = LENDIAN_TO_HOST_INT16(v);
491 return AF_SUCCEED;
494 status af_read_uint8 (uint8_t *value, AFvirtualfile *vf)
496 if (af_fread(value, 1, 1, vf) != 1)
497 return AF_FAIL;
498 return AF_SUCCEED;
501 status af_write_uint32_be (const uint32_t *value, AFvirtualfile *vf)
503 uint32_t v;
504 v = HOST_TO_BENDIAN_INT32(*value);
505 if (af_fwrite(&v, sizeof (v), 1, vf) != 1)
506 return AF_FAIL;
507 return AF_SUCCEED;
510 status af_write_uint32_le (const uint32_t *value, AFvirtualfile *vf)
512 uint32_t v;
513 v = HOST_TO_LENDIAN_INT32(*value);
514 if (af_fwrite(&v, sizeof (v), 1, vf) != 1)
515 return AF_FAIL;
516 return AF_SUCCEED;
519 status af_write_uint16_be (const uint16_t *value, AFvirtualfile *vf)
521 uint16_t v;
522 v = HOST_TO_BENDIAN_INT16(*value);
523 if (af_fwrite(&v, sizeof (v), 1, vf) != 1)
524 return AF_FAIL;
525 return AF_SUCCEED;
528 status af_write_uint16_le (const uint16_t *value, AFvirtualfile *vf)
530 uint16_t v;
531 v = HOST_TO_LENDIAN_INT16(*value);
532 if (af_fwrite(&v, sizeof (v), 1, vf) != 1)
533 return AF_FAIL;
534 return AF_SUCCEED;
537 status af_write_uint8 (const uint8_t *value, AFvirtualfile *vf)
539 if (af_fwrite(value, 1, 1, vf) != 1)
540 return AF_FAIL;
541 return AF_SUCCEED;
544 status af_read_pstring (char s[256], AFvirtualfile *vf)
546 uint8_t length;
547 /* Read the Pascal-style string containing the name. */
548 af_read_uint8(&length, vf);
549 af_fread(s, length, 1, vf);
550 s[length] = '\0';
551 return AF_SUCCEED;
554 status af_write_pstring (const char *s, AFvirtualfile *vf)
556 size_t length = strlen(s);
557 if (length > 255)
558 return AF_FAIL;
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)
568 uint8_t zero = 0;
569 af_write_uint8(&zero, vf);
571 return AF_SUCCEED;