(Metux) autogen.sh: not running ./configure anymore (breaks certain distro builders)
[mirror-ossqm-audiofile.git] / libaudiofile / next.c
blob59fa0d40d8fe95558bd24e564036eddc7e7fec18
1 /*
2 Audio File Library
3 Copyright (C) 1998-2000, Michael Pruett <michael@68k.org>
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.
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.
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.
22 next.c
24 This file contains routines for parsing NeXT/Sun .snd format sound
25 files.
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
32 #include <assert.h>
33 #include <stdint.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
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"
46 const int _af_next_compression_types[_AF_NEXT_NUM_COMPTYPES] =
48 AF_COMPRESSION_G711_ULAW,
49 AF_COMPRESSION_G711_ALAW
52 _AFfilesetup _af_next_default_filesetup =
54 _AF_VALID_FILESETUP, /* valid */
55 AF_FILE_NEXTSND, /* fileFormat */
56 true, /* trackSet */
57 true, /* instrumentSet */
58 true, /* miscellaneousSet */
59 1, /* trackCount */
60 NULL, /* tracks */
61 0, /* instrumentCount */
62 NULL, /* instruments */
63 0, /* miscellaneousCount */
64 NULL /* miscellaneous */
67 status _af_next_read_init (AFfilesetup setup, AFfilehandle file)
69 uint32_t id, offset, length, encoding, sampleRate, channelCount;
70 _Track *track;
72 assert(file != NULL);
73 assert(file->fh != NULL);
75 file->formatSpecific = NULL;
77 file->instruments = NULL;
78 file->instrumentCount = 0;
80 file->miscellaneous = NULL;
81 file->miscellaneousCount = 0;
83 file->tracks = NULL; /* Allocate this later. */
84 file->trackCount = 1;
86 af_fseek(file->fh, 0, SEEK_SET);
88 af_fread(&id, 4, 1, file->fh);
89 assert(!memcmp(&id, ".snd", 4));
91 af_read_uint32_be(&offset, file->fh);
92 af_read_uint32_be(&length, file->fh);
93 af_read_uint32_be(&encoding, file->fh);
94 af_read_uint32_be(&sampleRate, file->fh);
95 af_read_uint32_be(&channelCount, file->fh);
97 #ifdef DEBUG
98 printf("id, offset, length, encoding, sampleRate, channelCount:\n"
99 " %d %d %d %d %d %d\n",
100 id, offset, length, encoding, sampleRate, channelCount);
101 #endif
103 if ((track = _af_track_new()) == NULL)
104 return AF_FAIL;
106 file->tracks = track;
108 track->f.byteOrder = AF_BYTEORDER_BIGENDIAN;
110 /* Override the compression type later if necessary. */
111 track->f.compressionType = AF_COMPRESSION_NONE;
113 track->fpos_first_frame = offset;
114 track->data_size = af_flength(file->fh) - offset;
116 switch (encoding)
118 case _AU_FORMAT_MULAW_8:
119 track->f.sampleWidth = 16;
120 track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP;
121 track->f.compressionType = AF_COMPRESSION_G711_ULAW;
122 break;
123 case _AU_FORMAT_ALAW_8:
124 track->f.sampleWidth = 16;
125 track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP;
126 track->f.compressionType = AF_COMPRESSION_G711_ALAW;
127 break;
128 case _AU_FORMAT_LINEAR_8:
129 track->f.sampleWidth = 8;
130 track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP;
131 break;
132 case _AU_FORMAT_LINEAR_16:
133 track->f.sampleWidth = 16;
134 track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP;
135 break;
136 case _AU_FORMAT_LINEAR_24:
137 track->f.sampleWidth = 24;
138 track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP;
139 break;
140 case _AU_FORMAT_LINEAR_32:
141 track->f.sampleWidth = 32;
142 track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP;
143 break;
144 case _AU_FORMAT_FLOAT:
145 track->f.sampleWidth = 32;
146 track->f.sampleFormat = AF_SAMPFMT_FLOAT;
147 break;
148 case _AU_FORMAT_DOUBLE:
149 track->f.sampleWidth = 64;
150 track->f.sampleFormat = AF_SAMPFMT_DOUBLE;
151 break;
153 default:
155 This encoding method is not recognized.
157 _af_error(AF_BAD_SAMPFMT, "bad sample format");
158 return AF_FAIL;
161 _af_set_sample_format(&track->f, track->f.sampleFormat, track->f.sampleWidth);
163 track->f.sampleRate = sampleRate;
164 track->f.channelCount = channelCount;
165 int frameSize = _af_format_frame_size(&track->f, false);
166 track->totalfframes = length / frameSize;
168 #ifdef DEBUG
169 printf("_af_next_read_init\n");
170 _af_print_filehandle(file);
171 #endif
173 /* The file has been parsed successfully. */
174 return AF_SUCCEED;
177 bool _af_next_recognize (AFvirtualfile *fh)
179 uint8_t buffer[4];
181 af_fseek(fh, 0, SEEK_SET);
183 if (af_fread(buffer, 1, 4, fh) != 4 || memcmp(buffer, ".snd", 4) != 0)
184 return false;
186 return true;
189 AFfilesetup _af_next_complete_setup (AFfilesetup setup)
191 _TrackSetup *track;
193 if (setup->trackSet && setup->trackCount != 1)
195 _af_error(AF_BAD_NUMTRACKS, "NeXT files must have exactly 1 track");
196 return AF_NULL_FILESETUP;
199 track = _af_filesetup_get_tracksetup(setup, AF_DEFAULT_TRACK);
200 if (track->f.sampleFormat == AF_SAMPFMT_UNSIGNED)
202 _af_error(AF_BAD_FILEFMT, "NeXT format does not support unsigned data");
203 _af_set_sample_format(&track->f, AF_SAMPFMT_TWOSCOMP, track->f.sampleWidth);
206 if (track->f.sampleFormat == AF_SAMPFMT_TWOSCOMP)
208 if (track->f.sampleWidth != 8 &&
209 track->f.sampleWidth != 16 &&
210 track->f.sampleWidth != 24 &&
211 track->f.sampleWidth != 32)
213 _af_error(AF_BAD_WIDTH, "invalid sample width %d for NeXT file (only 8-, 16-, 24-, and 32-bit data are allowed)");
214 return AF_NULL_FILESETUP;
218 if (track->f.compressionType != AF_COMPRESSION_NONE &&
219 track->f.compressionType != AF_COMPRESSION_G711_ULAW &&
220 track->f.compressionType != AF_COMPRESSION_G711_ALAW)
222 _af_error(AF_BAD_NOT_IMPLEMENTED, "compression format not implemented for NeXT files");
223 return AF_NULL_FILESETUP;
226 if (track->f.byteOrder != AF_BYTEORDER_BIGENDIAN && track->byteOrderSet)
228 _af_error(AF_BAD_BYTEORDER, "NeXT format supports only big-endian data");
229 track->f.byteOrder = AF_BYTEORDER_BIGENDIAN;
232 if (track->aesDataSet)
234 _af_error(AF_BAD_FILESETUP, "NeXT files cannot have AES data");
235 return AF_NULL_FILESETUP;
238 if (track->markersSet && track->markerCount != 0)
240 _af_error(AF_BAD_FILESETUP, "NeXT format does not support markers");
241 return AF_NULL_FILESETUP;
244 if (setup->instrumentSet && setup->instrumentCount != 0)
246 _af_error(AF_BAD_FILESETUP, "NeXT format does not support instruments");
247 return AF_NULL_FILESETUP;
250 if (setup->miscellaneousSet && setup->miscellaneousCount != 0)
252 _af_error(AF_BAD_FILESETUP, "NeXT format does not support miscellaneous data");
253 return AF_NULL_FILESETUP;
256 return _af_filesetup_copy(setup, &_af_next_default_filesetup, false);