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

Revision 17099, 6.8 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) 1998-2000, Michael Pruett <michael@68k.org>
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        next.c
23
24        This file contains routines for parsing NeXT/Sun .snd format sound
25        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 <stdlib.h>
36#include <string.h>
37
38#include "next.h"
39#include "audiofile.h"
40#include "afinternal.h"
41#include "track.h"
42#include "util.h"
43#include "setup.h"
44#include "byteorder.h"
45
46int _af_next_compression_types[_AF_NEXT_NUM_COMPTYPES] =
47{
48        AF_COMPRESSION_G711_ULAW,
49        AF_COMPRESSION_G711_ALAW
50};
51
52_AFfilesetup _af_next_default_filesetup =
53{
54        _AF_VALID_FILESETUP,    /* valid */
55        AF_FILE_NEXTSND,        /* fileFormat */
56        AF_TRUE,                /* trackSet */
57        AF_TRUE,                /* instrumentSet */
58        AF_TRUE,                /* miscellaneousSet */
59        1,                      /* trackCount */
60        NULL,                   /* tracks */
61        0,                      /* instrumentCount */
62        NULL,                   /* instruments */
63        0,                      /* miscellaneousCount */
64        NULL                    /* miscellaneous */
65};
66
67status _af_next_read_init (AFfilesetup setup, AFfilehandle file)
68{
69        u_int32_t       id, offset, length, encoding, sampleRate, channelCount;
70        _Track          *track;
71
72        assert(file != NULL);
73        assert(file->fh != NULL);
74
75        file->formatSpecific = NULL;
76
77        file->instruments = NULL;
78        file->instrumentCount = 0;
79
80        file->miscellaneous = NULL;
81        file->miscellaneousCount = 0;
82
83        file->tracks = NULL;    /* Allocate this later. */
84        file->trackCount = 1;
85
86        af_fseek(file->fh, 0, SEEK_SET);
87
88        af_fread(&id, 4, 1, file->fh);
89        assert(!memcmp(&id, ".snd", 4));
90
91        af_fread(&offset, 4, 1, file->fh);
92        af_fread(&length, 4, 1, file->fh);
93        af_fread(&encoding, 4, 1, file->fh);
94        af_fread(&sampleRate, 4, 1, file->fh);
95        af_fread(&channelCount, 4, 1, file->fh);
96
97        offset = BENDIAN_TO_HOST_INT32(offset);
98        length = BENDIAN_TO_HOST_INT32(length);
99        encoding = BENDIAN_TO_HOST_INT32(encoding);
100        sampleRate = BENDIAN_TO_HOST_INT32(sampleRate);
101        channelCount = BENDIAN_TO_HOST_INT32(channelCount);
102
103#ifdef DEBUG
104        printf("id, offset, length, encoding, sampleRate, channelCount:\n"
105                " %d %d %d %d %d %d\n",
106                id, offset, length, encoding, sampleRate, channelCount);
107#endif
108
109        if ((track = _af_track_new()) == NULL)
110                return AF_FAIL;
111
112        file->tracks = track;
113
114        track->f.byteOrder = AF_BYTEORDER_BIGENDIAN;
115
116        /* Override the compression type later if necessary. */
117        track->f.compressionType = AF_COMPRESSION_NONE;
118
119        track->fpos_first_frame = offset;
120        track->data_size = af_flength(file->fh) - offset;
121
122        switch (encoding)
123        {
124                case _AU_FORMAT_MULAW_8:
125                        track->f.sampleWidth = 16;
126                        track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP;
127                        track->f.compressionType = AF_COMPRESSION_G711_ULAW;
128                        break;
129                case _AU_FORMAT_ALAW_8:
130                        track->f.sampleWidth = 16;
131                        track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP;
132                        track->f.compressionType = AF_COMPRESSION_G711_ALAW;
133                        break;
134                case _AU_FORMAT_LINEAR_8:
135                        track->f.sampleWidth = 8;
136                        track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP;
137                        break;
138                case _AU_FORMAT_LINEAR_16:
139                        track->f.sampleWidth = 16;
140                        track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP;
141                        break;
142                case _AU_FORMAT_LINEAR_24:
143                        track->f.sampleWidth = 24;
144                        track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP;
145                        break;
146                case _AU_FORMAT_LINEAR_32:
147                        track->f.sampleWidth = 32;
148                        track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP;
149                        break;
150                case _AU_FORMAT_FLOAT:
151                        track->f.sampleWidth = 32;
152                        track->f.sampleFormat = AF_SAMPFMT_FLOAT;
153                        break;
154                case _AU_FORMAT_DOUBLE:
155                        track->f.sampleWidth = 64;
156                        track->f.sampleFormat = AF_SAMPFMT_DOUBLE;
157                        break;
158
159                default:
160                        /*
161                                This encoding method is not recognized.
162                        */
163                        _af_error(AF_BAD_SAMPFMT, "bad sample format");
164                        return AF_FAIL;
165        }
166
167        _af_set_sample_format(&track->f, track->f.sampleFormat, track->f.sampleWidth);
168
169        track->f.sampleRate = sampleRate;
170        track->f.channelCount = channelCount;
171        track->totalfframes = length / _af_format_frame_size(&track->f, AF_FALSE);
172
173#ifdef DEBUG
174        printf("_af_next_read_init\n");
175        _af_print_filehandle(file);
176#endif
177
178        /* The file has been parsed successfully. */
179        return AF_SUCCEED;
180}
181
182bool _af_next_recognize (AFvirtualfile *fh)
183{
184        u_int8_t        buffer[4];
185
186        af_fseek(fh, 0, SEEK_SET);
187
188        if (af_fread(buffer, 1, 4, fh) != 4 || memcmp(buffer, ".snd", 4) != 0)
189                return AF_FALSE;
190
191        return AF_TRUE;
192}
193
194AFfilesetup _af_next_complete_setup (AFfilesetup setup)
195{
196        _TrackSetup     *track;
197
198        if (setup->trackSet && setup->trackCount != 1)
199        {
200                _af_error(AF_BAD_NUMTRACKS, "NeXT files must have exactly 1 track");
201                return AF_NULL_FILESETUP;
202        }
203
204        track = _af_filesetup_get_tracksetup(setup, AF_DEFAULT_TRACK);
205        if (track->f.sampleFormat == AF_SAMPFMT_UNSIGNED)
206        {
207                _af_error(AF_BAD_FILEFMT, "NeXT format does not support unsigned data");
208                _af_set_sample_format(&track->f, AF_SAMPFMT_TWOSCOMP, track->f.sampleWidth);
209        }
210
211        if (track->f.sampleFormat == AF_SAMPFMT_TWOSCOMP)
212        {
213                if (track->f.sampleWidth != 8 &&
214                        track->f.sampleWidth != 16 &&
215                        track->f.sampleWidth != 24 &&
216                        track->f.sampleWidth != 32)
217                {
218                        _af_error(AF_BAD_WIDTH, "invalid sample width %d for NeXT file (only 8-, 16-, 24-, and 32-bit data are allowed)");
219                        return AF_NULL_FILESETUP;
220                }
221        }
222
223        if (track->f.compressionType != AF_COMPRESSION_NONE &&
224                track->f.compressionType != AF_COMPRESSION_G711_ULAW &&
225                track->f.compressionType != AF_COMPRESSION_G711_ALAW)
226        {
227                _af_error(AF_BAD_NOT_IMPLEMENTED, "compression format not implemented for NeXT files");
228                return AF_NULL_FILESETUP;
229        }
230
231        if (track->f.byteOrder != AF_BYTEORDER_BIGENDIAN && track->byteOrderSet)
232        {
233                _af_error(AF_BAD_BYTEORDER, "NeXT format supports only big-endian data");
234                track->f.byteOrder = AF_BYTEORDER_BIGENDIAN;
235        }
236
237        if (track->aesDataSet)
238        {
239                _af_error(AF_BAD_FILESETUP, "NeXT files cannot have AES data");
240                return AF_NULL_FILESETUP;
241        }
242
243        if (track->markersSet && track->markerCount != 0)
244        {
245                _af_error(AF_BAD_FILESETUP, "NeXT format does not support markers");
246                return AF_NULL_FILESETUP;
247        }
248
249        if (setup->instrumentSet && setup->instrumentCount != 0)
250        {
251                _af_error(AF_BAD_FILESETUP, "NeXT format does not support instruments");
252                return AF_NULL_FILESETUP;
253        }
254
255        if (setup->miscellaneousSet && setup->miscellaneousCount != 0)
256        {
257                _af_error(AF_BAD_FILESETUP, "NeXT format does not support miscellaneous data");
258                return AF_NULL_FILESETUP;
259        }
260
261        return _af_filesetup_copy(setup, &_af_next_default_filesetup, AF_FALSE);
262}
Note: See TracBrowser for help on using the repository browser.