source: trunk/third/audiofile/libaudiofile/ircam.c @ 17099

Revision 17099, 7.5 KB checked in by ghudson, 23 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r17098, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2        Audio File Library
3        Copyright (C) 2001, Silicon Graphics, Inc.
4
5        This library is free software; you can redistribute it and/or
6        modify it under the terms of the GNU Library General Public
7        License as published by the Free Software Foundation; either
8        version 2 of the License, or (at your option) any later version.
9
10        This library 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 GNU
13        Library General Public License for more details.
14
15        You should have received a copy of the GNU Library General Public
16        License along with this library; if not, write to the
17        Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18        Boston, MA  02111-1307  USA.
19*/
20
21/*
22        ircam.c
23
24        This file contains routines for parsing Berkeley/IRCAM/CARL
25        format files.
26*/
27
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31
32#include <assert.h>
33#include <sys/types.h>
34#include <stdio.h>
35#include <string.h>
36
37#include "afinternal.h"
38#include "audiofile.h"
39#include "util.h"
40#include "byteorder.h"
41#include "setup.h"
42#include "track.h"
43#include "marker.h"
44
45#include "ircam.h"
46
47/*
48        These magic numbers are fucking stupid.
49
50        Here ircam_mips_magic refers to little-endian MIPS, not SGI IRIX,
51        which uses big-endian MIPS.
52*/
53const u_int8_t ircam_vax_magic[4] = {0x64, 0xa3, 0x01, 0x00},
54        ircam_sun_magic[4] = {0x64, 0xa3, 0x02, 0x00},
55        ircam_mips_magic[4] = {0x64, 0xa3, 0x03, 0x00},
56        ircam_next_magic[4] = {0x64, 0xa3, 0x04, 0x00};
57
58_AFfilesetup _af_ircam_default_filesetup =
59{
60        _AF_VALID_FILESETUP,    /* valid */
61        AF_FILE_IRCAM,          /* fileFormat */
62        AF_TRUE,                /* trackSet */
63        AF_TRUE,                /* instrumentSet */
64        AF_TRUE,                /* miscellaneousSet */
65        1,                      /* trackCount */
66        NULL,                   /* tracks */
67        0,                      /* instrumentCount */
68        NULL,                   /* instruments */
69        0,                      /* miscellaneousCount */
70        NULL                    /* miscellaneous */
71};
72
73bool _af_ircam_recognize (AFvirtualfile *fh)
74{
75        u_int8_t        buffer[4];
76
77        af_fseek(fh, 0, SEEK_SET);
78
79        if (af_fread(buffer, 4, 1, fh) != 1)
80                return AF_FALSE;
81
82        /* Check to see if the file's magic number matches. */
83        if (memcmp(buffer, ircam_vax_magic, 4) == 0 ||
84                memcmp(buffer, ircam_sun_magic, 4) == 0 ||
85                memcmp(buffer, ircam_mips_magic, 4) == 0 ||
86                memcmp(buffer, ircam_next_magic, 4) == 0)
87        {
88                return AF_TRUE;
89        }
90
91        return AF_FALSE;
92}
93
94AFfilesetup _af_ircam_complete_setup (AFfilesetup setup)
95{
96        _TrackSetup     *track;
97
98        if (setup->trackSet && setup->trackCount != 1)
99        {
100                _af_error(AF_BAD_NUMTRACKS, "BICSF file must have 1 track");
101                return AF_NULL_FILESETUP;
102        }
103
104        track = &setup->tracks[0];
105
106        if (track->sampleFormatSet)
107        {
108                if (track->f.sampleFormat == AF_SAMPFMT_UNSIGNED)
109                {
110                        _af_error(AF_BAD_SAMPFMT,
111                                "BICSF format does not support unsigned data");
112                        return AF_NULL_FILESETUP;
113                }
114
115                if (track->f.sampleFormat == AF_SAMPFMT_TWOSCOMP &&
116                        track->f.sampleWidth != 16)
117                {
118                        _af_error(AF_BAD_WIDTH,
119                                "BICSF format supports only 16-bit width for "
120                                "two's complement audio data");
121                        return AF_NULL_FILESETUP;
122                }
123
124                if (track->f.sampleFormat == AF_SAMPFMT_DOUBLE)
125                {
126                        _af_error(AF_BAD_SAMPFMT,
127                                "BICSF format does not support "
128                                "double-precision floating-point data");
129                        return AF_NULL_FILESETUP;
130                }
131        }
132
133        if (track->rateSet && track->f.sampleRate <= 0.0)
134        {
135                _af_error(AF_BAD_RATE,
136                        "invalid sample rate %.30g for BICSF file",
137                        track->f.sampleRate);
138                return AF_NULL_FILESETUP;
139        }
140
141        if (track->channelCountSet && track->f.channelCount != 1 &&
142                track->f.channelCount != 2 && track->f.channelCount != 4)
143        {
144                _af_error(AF_BAD_CHANNELS,
145                        "invalid channel count (%d) for BICSF format "
146                        "(1, 2, or 4 channels only)",
147                        track->f.channelCount);
148                return AF_NULL_FILESETUP;
149        }
150
151        if (track->compressionSet &&
152                track->f.compressionType != AF_COMPRESSION_NONE)
153        {
154                _af_error(AF_BAD_NOT_IMPLEMENTED,
155                        "BICSF format does not support compression");
156                return AF_NULL_FILESETUP;
157        }
158
159        if (track->aesDataSet)
160        {
161                _af_error(AF_BAD_FILESETUP, "BICSF file cannot have AES data");
162                return AF_NULL_FILESETUP;
163        }
164
165        if (track->markersSet && track->markerCount != 0)
166        {
167                _af_error(AF_BAD_NUMMARKS, "BICSF format does not support markers");
168                return AF_NULL_FILESETUP;
169        }
170
171        if (setup->instrumentSet && setup->instrumentCount != 0)
172        {
173                _af_error(AF_BAD_NUMINSTS, "BICSF format does not support instruments");
174                return AF_NULL_FILESETUP;
175        }
176
177        /* XXXmpruett: We don't support miscellaneous chunks for now. */
178        if (setup->miscellaneousSet && setup->miscellaneousCount != 0)
179        {
180                _af_error(AF_BAD_NOT_IMPLEMENTED, "BICSF format does not currently support miscellaneous chunks");
181                return AF_NULL_FILESETUP;
182        }
183
184        return _af_filesetup_copy(setup, &_af_ircam_default_filesetup, AF_TRUE);
185}
186
187status _af_ircam_read_init (AFfilesetup setup, AFfilehandle handle)
188{
189        _Track          *track;
190        u_int8_t        magic[4];
191        float           rate;
192        u_int32_t       channels;
193        u_int32_t       packMode;
194
195        float           maxAmp = 1.0;
196
197        bool            isSwapped, isLittleEndian;
198
199        handle->instruments = NULL;
200        handle->instrumentCount = 0 ;
201        handle->miscellaneous = NULL;
202        handle->miscellaneousCount = 0;
203
204        handle->tracks = NULL;
205        handle->trackCount = 1;
206
207        af_fseek(handle->fh, 0, SEEK_SET);
208
209        if (af_fread(magic, 4, 1, handle->fh) != 1)
210        {
211                _af_error(AF_BAD_READ, "Could not read BICSF file header");
212                return AF_FAIL;
213        }
214
215        if (memcmp(magic, ircam_vax_magic, 4) != 0 &&
216                memcmp(magic, ircam_sun_magic, 4) != 0 &&
217                memcmp(magic, ircam_mips_magic, 4) != 0 &&
218                memcmp(magic, ircam_next_magic, 4) != 0)
219        {
220                _af_error(AF_BAD_FILEFMT,
221                        "file is not a BICSF file (bad magic number)");
222                return AF_FAIL;
223        }
224
225        /*
226                If the file's magic number is that for VAX or MIPS,
227                the file is little endian.
228        */
229        isLittleEndian = (memcmp(magic, ircam_vax_magic, 4) == 0 ||
230                memcmp(magic, ircam_mips_magic, 4) == 0);
231
232#ifdef WORDS_BIGENDIAN
233        isSwapped = isLittleEndian;
234#else
235        isSwapped = !isLittleEndian;
236#endif
237
238        af_fread(&rate, 4, 1, handle->fh);
239        af_fread(&channels, 4, 1, handle->fh);
240        af_fread(&packMode, 4, 1, handle->fh);
241
242        if (isSwapped)
243        {
244                rate = _af_byteswap_float32(rate);
245                channels = _af_byteswap_int32(channels);
246                packMode = _af_byteswap_int32(packMode);
247        }
248
249        if ((handle->tracks = _af_track_new()) == NULL)
250                return AF_FAIL;
251
252        track = &handle->tracks[0];
253
254        track->f.sampleRate = rate;
255        track->f.compressionType = AF_COMPRESSION_NONE;
256
257        switch (packMode)
258        {
259                case SF_SHORT:
260                        track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP;
261                        track->f.sampleWidth = 16;
262                        break;
263                case SF_FLOAT:
264                        track->f.sampleFormat = AF_SAMPFMT_FLOAT;
265                        track->f.sampleWidth = 32;
266                        break;
267                default:
268                        _af_error(AF_BAD_NOT_IMPLEMENTED,
269                                "BICSF data format %d not supported", packMode);
270                        return AF_FAIL;
271        }
272
273        track->f.channelCount = channels;
274        if (channels != 1 && channels != 2 && channels != 4)
275        {
276                _af_error(AF_BAD_FILEFMT, "invalid channel count (%d) "
277                        "for BICSF format (1, 2, or 4 only)",
278                        channels);
279                return AF_FAIL;
280        }
281
282        if (isLittleEndian)
283                track->f.byteOrder = AF_BYTEORDER_LITTLEENDIAN;
284        else
285                track->f.byteOrder = AF_BYTEORDER_BIGENDIAN;
286
287        if (_af_set_sample_format(&track->f, track->f.sampleFormat,
288                track->f.sampleWidth) == AF_FAIL)
289        {
290                return AF_FAIL;
291        }
292
293        if (track->f.sampleFormat == AF_SAMPFMT_FLOAT)
294                track->f.pcm.slope = maxAmp;
295
296        track->data_size = af_flength(handle->fh) - SIZEOF_BSD_HEADER;
297
298        /*
299                Only uncompressed data formats are supported for IRCAM
300                files right now.  The following line would need to be
301                changed if compressed data formats were supported.
302        */
303        track->totalfframes = track->data_size /
304                _af_format_frame_size(&track->f, AF_FALSE);
305
306        track->fpos_first_frame = SIZEOF_BSD_HEADER;
307        track->nextfframe = 0;
308        track->fpos_next_frame = track->fpos_first_frame;
309
310        handle->formatSpecific = NULL;
311
312        return AF_SUCCEED;
313}
Note: See TracBrowser for help on using the repository browser.