3 Copyright (C) 2004, 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.
24 This file contains code for reading NIST SPHERE files.
37 #include "afinternal.h"
38 #include "audiofile.h"
40 #include "byteorder.h"
46 _AFfilesetup _af_nist_default_filesetup
=
48 _AF_VALID_FILESETUP
, /* valid */
49 AF_FILE_NIST_SPHERE
, /* fileFormat */
51 true, /* instrumentSet */
52 true, /* miscellaneousSet */
55 0, /* instrumentCount */
56 NULL
, /* instruments */
57 0, /* miscellaneousCount */
58 NULL
/* miscellaneous */
61 bool _af_nist_recognize (AFvirtualfile
*fh
)
65 af_fseek(fh
, 0, SEEK_SET
);
67 if (af_fread(buffer
, 16, 1, fh
) != 1)
70 /* Check to see if the file's magic number matches. */
71 if (memcmp(buffer
, "NIST_1A\n 1024\n", 16) == 0)
77 AFfilesetup
_af_nist_complete_setup (AFfilesetup setup
)
81 if (setup
->trackSet
&& setup
->trackCount
!= 1)
83 _af_error(AF_BAD_NUMTRACKS
, "NIST SPHERE file must have 1 track");
84 return AF_NULL_FILESETUP
;
87 track
= &setup
->tracks
[0];
89 if (track
->sampleFormatSet
)
91 /* XXXmpruett: Currently we allow only 1-16 bit sample width. */
92 if (track
->f
.sampleFormat
== AF_SAMPFMT_TWOSCOMP
&&
93 (track
->f
.sampleWidth
< 1 || track
->f
.sampleWidth
> 16))
95 _af_error(AF_BAD_WIDTH
,
96 "invalid sample width %d bits for NIST SPHERE format");
97 return AF_NULL_FILESETUP
;
99 else if (track
->f
.sampleFormat
== AF_SAMPFMT_UNSIGNED
)
101 _af_error(AF_BAD_SAMPFMT
,
102 "NIST SPHERE format does not support unsigned data");
103 return AF_NULL_FILESETUP
;
105 else if (track
->f
.sampleFormat
== AF_SAMPFMT_FLOAT
||
106 track
->f
.sampleFormat
== AF_SAMPFMT_DOUBLE
)
108 _af_error(AF_BAD_SAMPFMT
,
109 "NIST SPHERE format does not support floating-point data");
110 return AF_NULL_FILESETUP
;
114 if (track
->rateSet
&& track
->f
.sampleRate
<= 0.0)
116 _af_error(AF_BAD_RATE
,
117 "invalid sample rate %.30g for NIST SPHERE file",
118 track
->f
.sampleRate
);
119 return AF_NULL_FILESETUP
;
122 if (track
->channelCountSet
&& track
->f
.channelCount
< 1)
124 _af_error(AF_BAD_CHANNELS
,
125 "invalid channel count (%d) for NIST SPHERE format",
126 track
->f
.channelCount
);
127 return AF_NULL_FILESETUP
;
130 if (track
->compressionSet
&& track
->f
.compressionType
!= AF_COMPRESSION_NONE
&&
131 track
->f
.compressionType
!= AF_COMPRESSION_G711_ULAW
&&
132 track
->f
.compressionType
!= AF_COMPRESSION_G711_ALAW
)
134 _af_error(AF_BAD_NOT_IMPLEMENTED
,
135 "NIST SPHERE format supports only G.711 u-law or A-law compression");
136 return AF_NULL_FILESETUP
;
139 if (track
->aesDataSet
)
141 _af_error(AF_BAD_FILESETUP
, "NIST SPHERE file cannot have AES data");
142 return AF_NULL_FILESETUP
;
145 if (track
->markersSet
&& track
->markerCount
!= 0)
147 _af_error(AF_BAD_NUMMARKS
, "NIST SPHERE format does not support markers");
148 return AF_NULL_FILESETUP
;
151 if (setup
->instrumentSet
&& setup
->instrumentCount
!= 0)
153 _af_error(AF_BAD_NUMINSTS
, "NIST SPHERE format does not support instruments");
154 return AF_NULL_FILESETUP
;
157 /* XXXmpruett: We don't support miscellaneous chunks for now. */
158 if (setup
->miscellaneousSet
&& setup
->miscellaneousCount
!= 0)
160 _af_error(AF_BAD_NOT_IMPLEMENTED
, "NIST SPHERE format does not currently support miscellaneous chunks");
161 return AF_NULL_FILESETUP
;
164 return _af_filesetup_copy(setup
, &_af_nist_default_filesetup
, true);
167 static bool nist_header_read_int (char *header
, char *key
, int *val
)
170 char keystring
[256], scanstring
[256];
172 snprintf(keystring
, 256, "\n%s -i", key
);
174 if ((cp
= strstr(header
, keystring
)) != NULL
)
176 snprintf(scanstring
, 256, "\n%s -i %%d", key
);
177 sscanf(cp
, scanstring
, val
);
184 static bool nist_header_read_string (char *header
, char *key
, int *length
, char *val
)
187 char keystring
[256], scanstring
[256];
189 snprintf(keystring
, 256, "\n%s -s", key
);
191 if ((cp
= strstr(header
, keystring
)) != NULL
)
193 snprintf(scanstring
, 256, "\n%s -s%%d %%79s", key
);
194 sscanf(cp
, scanstring
, length
, val
);
201 status
_af_nist_read_init (AFfilesetup setup
, AFfilehandle handle
)
204 char header
[NIST_SPHERE_HEADER_LENGTH
+ 1];
206 char strval
[NIST_SPHERE_MAX_FIELD_LENGTH
];
209 handle
->instruments
= NULL
;
210 handle
->instrumentCount
= 0 ;
211 handle
->miscellaneous
= NULL
;
212 handle
->miscellaneousCount
= 0;
214 handle
->tracks
= NULL
;
215 handle
->trackCount
= 1;
217 af_fseek(handle
->fh
, 0, SEEK_SET
);
219 if (af_fread(header
, NIST_SPHERE_HEADER_LENGTH
, 1, handle
->fh
) != 1)
221 _af_error(AF_BAD_READ
, "Could not read NIST SPHERE file header");
225 header
[NIST_SPHERE_HEADER_LENGTH
] = '\0';
227 if (memcmp(header
, "NIST_1A\n 1024\n", 16) != 0)
229 _af_error(AF_BAD_FILEFMT
, "Bad NIST SPHERE file header");
233 if ((handle
->tracks
= _af_track_new()) == NULL
)
235 track
= &handle
->tracks
[0];
237 /* Read number of bytes per sample. */
238 if (!nist_header_read_int(header
, "sample_n_bytes", &sample_n_bytes
))
240 _af_error(AF_BAD_HEADER
, "bytes per sample not specified");
245 Since some older NIST SPHERE files lack a sample_coding
246 field, if sample_n_bytes is 1, assume mu-law;
247 otherwise assume linear PCM.
249 track
->f
.sampleFormat
= AF_SAMPFMT_TWOSCOMP
;
250 if (sample_n_bytes
== 1)
252 track
->f
.compressionType
= AF_COMPRESSION_G711_ULAW
;
253 track
->f
.sampleWidth
= 16;
257 track
->f
.compressionType
= AF_COMPRESSION_NONE
;
258 track
->f
.sampleWidth
= sample_n_bytes
* 8;
261 if (nist_header_read_string(header
, "sample_coding", &intval
, strval
))
263 if (strcmp(strval
, "pcm") == 0)
265 else if (strcmp(strval
, "ulaw") == 0 || strcmp(strval
, "mu-law") == 0)
267 track
->f
.compressionType
= AF_COMPRESSION_G711_ULAW
;
268 track
->f
.sampleWidth
= 16;
270 else if (strcmp(strval
, "alaw") == 0)
272 track
->f
.compressionType
= AF_COMPRESSION_G711_ALAW
;
273 track
->f
.sampleWidth
= 16;
277 _af_error(AF_BAD_SAMPFMT
,
278 "unrecognized NIST SPHERE sample format %s", strval
);
283 /* Read channel count. */
284 if (nist_header_read_int(header
, "channel_count", &intval
))
288 _af_error(AF_BAD_CHANNELS
, "invalid number of channels %d",
292 track
->f
.channelCount
= intval
;
296 _af_error(AF_BAD_HEADER
, "number of channels not specified");
300 /* Read string representing byte order. */
301 if (nist_header_read_string(header
, "sample_byte_format", &intval
, strval
))
305 if (strncmp(strval
, "01", 2) == 0)
306 track
->f
.byteOrder
= AF_BYTEORDER_LITTLEENDIAN
;
308 track
->f
.byteOrder
= AF_BYTEORDER_BIGENDIAN
;
311 track
->f
.byteOrder
= _AF_BYTEORDER_NATIVE
;
316 Fail if this field is not present and sample
317 width is more than one byte.
319 if (track
->f
.compressionType
== AF_COMPRESSION_NONE
&&
320 track
->f
.sampleWidth
> 8)
322 _af_error(AF_BAD_HEADER
, "sample byte order not specified");
327 /* Read significant bits per sample. */
328 if (nist_header_read_int(header
, "sample_sig_bits", &intval
))
330 if (intval
< 1 || intval
> 32)
332 _af_error(AF_BAD_WIDTH
, "invalid sample width %d bits\n",
338 Use specified significant bits value as the
339 sample width for uncompressed data as long
340 as the number of bytes per sample remains
343 if (track
->f
.compressionType
== AF_COMPRESSION_NONE
&&
344 (intval
+ 7) / 8 == sample_n_bytes
)
346 track
->f
.sampleWidth
= intval
;
350 /* Read sample rate. */
351 if (nist_header_read_int(header
, "sample_rate", &intval
))
355 _af_error(AF_BAD_RATE
, "invalid sample rate %d Hz\n", intval
);
358 track
->f
.sampleRate
= intval
;
362 _af_error(AF_BAD_HEADER
, "sample rate not specified");
366 /* Read sample count. */
367 if (nist_header_read_int(header
, "sample_count", &intval
))
369 track
->totalfframes
= intval
/ track
->f
.channelCount
;
373 _af_error(AF_BAD_HEADER
, "number of samples not specified");
377 if (_af_set_sample_format(&track
->f
, track
->f
.sampleFormat
,
378 track
->f
.sampleWidth
) == AF_FAIL
)
383 track
->fpos_first_frame
= NIST_SPHERE_HEADER_LENGTH
;
384 track
->data_size
= af_flength(handle
->fh
) - NIST_SPHERE_HEADER_LENGTH
;
385 track
->nextfframe
= 0;
386 track
->fpos_next_frame
= track
->fpos_first_frame
;
388 handle
->formatSpecific
= NULL
;