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.
24 This file contains routines for parsing NeXT/Sun .snd format sound
39 #include "audiofile.h"
40 #include "afinternal.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 */
57 true, /* instrumentSet */
58 true, /* miscellaneousSet */
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
;
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. */
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
);
98 printf("id, offset, length, encoding, sampleRate, channelCount:\n"
99 " %d %d %d %d %d %d\n",
100 id
, offset
, length
, encoding
, sampleRate
, channelCount
);
103 if ((track
= _af_track_new()) == NULL
)
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
;
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
;
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
;
128 case _AU_FORMAT_LINEAR_8
:
129 track
->f
.sampleWidth
= 8;
130 track
->f
.sampleFormat
= AF_SAMPFMT_TWOSCOMP
;
132 case _AU_FORMAT_LINEAR_16
:
133 track
->f
.sampleWidth
= 16;
134 track
->f
.sampleFormat
= AF_SAMPFMT_TWOSCOMP
;
136 case _AU_FORMAT_LINEAR_24
:
137 track
->f
.sampleWidth
= 24;
138 track
->f
.sampleFormat
= AF_SAMPFMT_TWOSCOMP
;
140 case _AU_FORMAT_LINEAR_32
:
141 track
->f
.sampleWidth
= 32;
142 track
->f
.sampleFormat
= AF_SAMPFMT_TWOSCOMP
;
144 case _AU_FORMAT_FLOAT
:
145 track
->f
.sampleWidth
= 32;
146 track
->f
.sampleFormat
= AF_SAMPFMT_FLOAT
;
148 case _AU_FORMAT_DOUBLE
:
149 track
->f
.sampleWidth
= 64;
150 track
->f
.sampleFormat
= AF_SAMPFMT_DOUBLE
;
155 This encoding method is not recognized.
157 _af_error(AF_BAD_SAMPFMT
, "bad sample format");
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
;
169 printf("_af_next_read_init\n");
170 _af_print_filehandle(file
);
173 /* The file has been parsed successfully. */
177 bool _af_next_recognize (AFvirtualfile
*fh
)
181 af_fseek(fh
, 0, SEEK_SET
);
183 if (af_fread(buffer
, 1, 4, fh
) != 4 || memcmp(buffer
, ".snd", 4) != 0)
189 AFfilesetup
_af_next_complete_setup (AFfilesetup setup
)
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);